Много вопросов «когда генерировать исключение или возвращаемое значение» задавалось много (см. Ниже, чтобы увидеть только один пример):
Должен ли метод поиска возвращать 'null' или генерировать исключение, если он не может получить возвращаемое значение?
и я полностью согласен с ответами в основном.
Теперь мой вопрос возникает из-за добавления немного большего контекста к вышесказанному при применении этого к более сложной системе. Я постараюсь сделать это как можно более кратким и простым.
Хорошо, у нас есть пример приложения MVC PHP:
Модель A: имеет функцию get_car ($ id), которая возвращает объект автомобиля.
Контроллер А имеет простую функцию, например, для отображения автомобиля пользователю
Контроллер B, однако, имеет сложную функцию, которая, скажем, получает автомобиль, модифицирует его (скажем, с помощью одной из функций набора модели A), а также обновляет другие таблицы на основе некоторых из этих новых значений через другие модели и библиотеки по всей системе - очень комплекс ау лол
Теперь мы переходим к основной части моего вопроса:
Для целостности данных я хочу использовать транзакции MySQL. Здесь я сталкиваюсь со сценарием «что лучше / что лучше» ...
Мы пишем Модель A, чтобы она возвращала FALSE, если автомобиль не найден или имеется ошибка SQL.
Это нормально для контроллера A, так как он просто хочет знать, произошла ли ошибка и произошла ошибка, поэтому мы просто проверяем возвращаемое значение и bom - отлично.
Теперь мы переходим к контроллеру B. Контроллер B, скажем, выполняет некоторое обновление базы данных перед вызовом функции модели A, которую нам нужно откатить при ошибке, поэтому нам нужно использовать транзакции. теперь я дохожу до своей проблемы. оставить модель A в качестве возвращаемого значения и просто проверить его или изменить его, чтобы вызвать исключение с ударным эффектом, а затем переписать контроллер A, поскольку теперь нам нужно перехватить исключение ... then (не еще не сделано; о)) откатиться ли я в улове модели (но как мы узнаем, использовалась ли транзакция или нет?), или мы поймаем и перебросим или позволим всплывать до улова контроллера и сделать откат туда?
Я пытаюсь сказать, что если у меня много моделей и контроллеров с взаимодействием с базой данных, я должен просто заставить их генерировать исключения, а затем обернуть весь мой другой код, например, функции контроллера в try-ловушках всегда содержат модель или библиотечные функции. бросить, или, я могу сделать модели "автономными", чтобы привести в порядок и справиться с их собственными проблемами, но тогда что мне делать с откатом транзакции, если (для этого "вызова") одна была открыта (согласно моему примеру выше, не каждому время открытия транзакции ...)? если бы это было так, мне пришлось бы заставить все мои функции возвращать что-то и затем проверять это в контроллере, так как это единственное место, которое знает, есть ли открытая транзакция или нет ...
Итак, чтобы уточнить, я могу использовать try catch для перехвата и отката в контроллере, это нормально, но как мне сделать это «дальше вниз», например, в модели или в библиотечной функции ... которую можно вызвать как во время транзакции или просто как обычный вызов MySQL для автоматической фиксации?
Было бы неплохо объяснить ответ (так как мне нравится понимать, почему я что-то делаю), но если бы не какой-то голос за фаворита из следующих решений (хорошо, решения, которые я вижу):
1) сделать так, чтобы все функции модели и библиотеки всегда возвращали значение, а затем контроллер может либо просто запустить, либо выполнить попытку try для отката в случае необходимости, но это означает, что мне придется проверять возвращаемое значение каждой модели и библиотеки работают везде, где они используются.
2) заставить все функции модели и библиотеки генерировать исключения (скажем, при ошибке SQL) и обернуть каждый контроллер (который будет вызывать функции модели и библиотеки) в перехвате try, где перехватчик либо просто сработает, либо откатится при необходимости. ..
также, пожалуйста, обратите внимание, что "bom" толкает пользователя куда-то или показывает довольно большую ошибку (до того, как кто-то скажет "это плохая практика - просто позволить вашему приложению умереть ...", смеется)
Я надеюсь, вы получите, гдеЯ иду отсюда и прошу прощения за длинный нерешительный вопрос.
Заранее спасибо, Бен