Hibernate, Spring, @Transactional - окружить с помощью try / catch? - PullRequest
6 голосов
/ 21 марта 2011

Я работаю над разработкой веб-приложения для Spring 3 и Hibernate 3.6.У меня есть несколько вопросов к аннотации @Transactional и структуре кода.

-> Когда я использую @Transactional (управление транзакциями в Spring), нужно ли мне окружать методы, аннотированные @Transactionalс try / catch при их вызове?

Например, когда я получил метод, который загружает, изменяет и возвращает объект, и я вызываю его из другого класса: должен ли я окружить вызов try / catch?может быть, что-то идет не так, объект не возвращается, соединение с базой данных не удается .. Я не знаю.

До сих пор я думал, что @Transactional заботится обо всех возможных возникающих исключениях и откатывает каждую операцию в этой транзакции при возникновении ошибкипроисходит.но если это произойдет, я должен как-то проинформировать пользователя.когда я вызываю транзакционный метод в блоке try, и он откатывается, блок catch активируется?Тогда я могу сказать пользователю "что-то пошло не так".В противном случае пользователь, возможно, не был бы проинформирован?

Или достаточно проверить, возвращен ли объект (если / еще), тогда мне не нужно try / catch?Я новичок, и я хотел бы услышать, как другие структурируют их код.Спасибо: -)

Ответы [ 3 ]

4 голосов
/ 21 марта 2011

Обработка исключений в Spring действительно легко с HandlerExceptionResolvers и @ExceptionHandlers.Я склонен использовать исключительно @ExceptionHandler.

Вы можете использовать @ ExceptionHandler для обработки конкретного исключения вместо того, чтобы обрабатывать его самостоятельно в блоке try-catch.

Еслипользователь хотел ресурс, который не был найден, и вы хотите отправить 404.

@ExceptionHandler(NotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public void handleNotFoundException(NotFoundException exc) {
  // log something.
}

Если возникла проблема с сервером, на которую вы хотели бы отправить 500

@ExceptionHandler(SomeException.class)
public void handleException(SomeException exc, WebRequest request, HttpServletResponse response) {
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Sorry dude, my server broke");
}

Вы также должны тщательно обработать исключения.В общем, вы не должны делать @ExceptionHandler(Exception.class), и я также считаю, что он работает по порядку, поэтому, если вы обрабатываете общее исключение, это должен быть последний метод в классе.

1 голос
/ 21 марта 2011

Ключевой функцией, используемой Spring, является Перевод исключений .

полагайтесь на трансляцию исключений для генерации исключений, которые понимает ваш клиентский уровень, и используйте, по возможности, только try / catch там.

0 голосов
/ 21 марта 2011

спасибо, что ответили мне. Я прочитал ссылку (весенняя документация) и обнаружил следующее:

"Однако DAO выдает простое HibernateException (которое не проверяется, поэтому его не нужно объявлять или перехватывать), что означает, что вызывающие абоненты могут обрабатывать исключения только как обычно фатальные - если они не хотят зависеть от собственной иерархии исключений Hibernate. Выявление определенных причин, таких как сбой оптимистической блокировки, невозможно без привязки вызывающей стороны к стратегии реализации. Этот компромисс может быть приемлемым для приложений, которые сильно основаны на Hibernate и / или не нуждаются в какой-либо специальной обработке исключений. "

Мой DAO основан на Plain Hibernate 3 API, поэтому, если я правильно понимаю, мой DAO выдает только простые исключения HibernateException. Они не проверяются и не должны быть объявлены или пойманы. Если что-то идет не так, с @Transactional вся операция откатывается.

Чтобы убедиться, что все работает так, как я ожидал, я должен привязать свой DAO еще ближе к коду моего приложения. Там я могу проверить, например, возвращен ли объект или нет. (если ноль - иначе) Я также мог поймать исключение, зарегистрировать его и сообщить пользователю, что что-то пошло не так и что его транзакция не сработала.

Так что на данный момент, я все еще думаю, что - в зависимости от транзакции: если я могу работать с результатом, все в порядке - если нет, я могу сообщить пользователю.

когда транзакция не указана для возврата результата, я могу использовать try / catch для отлова HibernateException. Но транзакция все еще откатывается тогда? Я думал, что перехват HibernateException позволяет избежать отката транзакции. Я до сих пор не знаю, что делать. : - (

Кроме этого, к сожалению, я не понимаю, какое отношение к этому имеет обработка исключений MVC (@ExceptionHandler). Была таблица обработанных исключений, но я не нашел HibernateException. Или вы думаете, это будет работать с этим: @ExceptionHandler (HibernateException.classs)? также вы сказали, что не будете рекомендовать обрабатывать исключения таким образом.

...