Главная » Spring » Знакомство с иерархией исключений доступа к данным в Spring

0

Существует старый анекдот про парашютиста, которого снесло ветром на дерево, и он повис в нескольких метрах над землей. Спус- тя некоторое время появляется случайный прохожий, у которого незадачливый парашютист спрашивает, где он находится.

Прохожий: «Вы в шести метрах над землей». Парашютист: «Вы, должно быть, программист?» Прохожий: «Да, но как вы догадались?»

Парашютист: «Вы дали точный, но совершенно бессмысленный ответ».

Я слышал этот анекдот в разных вариациях, где прохожий имел разные профессии и национальности. Но он очень напоминает по- ложение дел с исключением SQLException в JDBC. Если вам когда- нибудь приходилось работать с JDBC (без использования Spring), то вы наверняка хорошо знаете, что в JDBC и шагу нельзя ступить без необходимости перехватывать исключение SQLException. Это исклю- чение свидетельствует, что произошла какая-то ошибка при обра- щении к базе данных, но оно содержит слишком мало информации о том, в чем, собственно, заключается ошибка и как ее обрабатывать.

В число распространенных проблем, которые могут вызывать ис- ключение SQLException, входят:

# приложение не может подключиться к базе данных;

# выполняемый запрос имеет синтаксические ошибки;

# таблицы и/или столбцы, упомянутые в запросе, не существуют;

# попытка вставить или обновить значения нарушает ограниче- ния базы данных.

Самый сложный вопрос, связанный с исключением SQLException определить, как правильно его обработать. Как оказывается, многие проблемы, вызвавшие исключение SQLException, не могут быть об- работаны в блоке catch. Большинство исключений SQLException озна- чают фатальную ошибку. Если приложение не может подключить- ся к базе данных, это обычно означает, что приложение не может продолжать работу. Аналогично, если ошибка содержится в запросе, трудно что-то сделать с этим во время выполнения.

Если после появления исключения SQLException ничего нельзя сделать для нормального продолжения работы приложения, зачем тогда его перехватывать?

Даже при наличии алгоритма решения некоторых проблем, свя- занных с исключением SQLException, вам все равно придется пере- хватить исключение SQLException и разбираться в его свойствах для получения дополнительной информации о характере проблемы. Это обусловлено тем, что исключение SQLException представляет собой

«один ответ на все проблемы», связанные с доступом к данным. Вместо того чтобы иметь разные типы исключений для каждой воз- можной проблемы, используется исключение SQLException, которое возбуждается при любых проблемах доступа к данным.

Некоторые фреймворки доступа к базам данных предлагают более разнообразные иерархии исключений. Hibernate, например, предлагает около двух десятков различных исключений, каждое из которых соответствует определенной проблеме. Это делает воз- можным написать блоки catch для конкретных исключений, которые предполагается обрабатывать.

Но следует понимать, что исключения, реализованные в Hibernate, являются специфичными для этого фреймворка. А как было сказано выше, желательно было бы изолировать специфику механизма хра- нения в слое доступа к данным. Если в этом слое возбуждаются ис- ключения Hibernate, то факт использования фреймворка Hibernate вне всяких сомнений просочится в остальные части приложения. Таким образом, или с этим придется смириться, или преобразовы- вать перехваченные исключения в некие новые, универсальные ис- ключения, возбуждая их повторно.

С одной стороны, иерархия исключений JDBC является слиш- ком общей. Фактически ее трудно даже назвать иерархией. С другой стороны, иерархия исключений в Hibernate является характерной для Hibernate. Нам же необходима иерархия исключений, достаточ- но информативная, но не связанная непосредственно с конкретным фреймворком доступа к данным.

Универсальная иерархия исключений в Spring

Модуль Spring JDBC реализует собственную иерархию исключе- ний доступа к данным, позволяющую решить обе проблемы. В от- личие от JDBC, в Spring имеются несколько исключений доступа к данным, каждое из которых описывает причины их возникнове- ния. В табл. 6.1 приводится сравнение некоторых исключений до- ступа к данным в Spring и в JDBC.

Как видно из таблицы, исключения в Spring описывают практи- чески все, что может произойти во время чтения или записи дан- ных в базу. Кроме того, в табл. 6.1 перечислены далеко не все ис-

ключения доступа к данным, поддерживаемые фреймворком Spring. (Я мог бы перечислить их все, но мне не хотелось вызвать ощущение неполноценности JDBC.)

Хотя иерархия исключений в Spring гораздо богаче, чем прос- тое исключение SQLException в JDBC, она не связана с каким-либо конкретным решением. Это означает, что фреймворк Spring будет возбуждать одни и те же исключения независимо от выбранного механизма доступа к данным. Это поможет изолировать выбранное решение в слое доступа к данным.

Таблица 6.1. Иерархия исключений JDBC в сравнении с исключениями доступа к данным в Spring

Исключения JDBC

Исключения доступа к данным в Spring

BatchUpdateException DataTruncation SQLException SQLWarning

CannotAcquireLockException CannotSerializeTransactionException CleanupFailureDataAccessException ConcurrencyFailureException DataAccessException DataAccessResourceFailureException DataIntegrityViolationException DataRetrievalFailureException DeadlockLoserDataAccessException EmptyResultDataAccessException IncorrectResultSizeDataAccessException IncorrectUpdateSemanticsDataAccessException InvalidDataAccessApiUsageException InvalidDataAccessResourceUsageException OptimisticLockingFailureException PermissionDeniedDataAccessException PessimisticLockingFailureException TypeMismatchDataAccessException UncategorizedDataAccessException

Смотрите! Мы избавились от блоков catch!

Из табл. 6.1 не очевидно, что все эти исключения наследуют исклю- чение DataAccessException. Особенность исключения DataAccessException состоит в том, что оно является неконтролируемым исключением. Другими словами, нет необходимости перехватывать  исключе- ния доступа к данным, возбуждаемые фреймворком Spring (хотя при желании это возможно).

Исключение DataAccessException – это лишь частный пример мно- гогранной философии Spring противопоставления контролируемых и неконтролируемых исключений. Фреймворк Spring придержива-

ется позиции, согласно которой многие исключения являются ре- зультатом проблем, не разрешимых в блоке catch. Вместо того чтобы вынуждать разработчиков писать блоки обработки исключений (ко- торые часто остаются пустыми), Spring продвигает идею неконтро- лируемых исключений. Это позволяет оставить решение о выборе места обработки исключений за разработчиком.

Чтобы воспользоваться преимуществами исключений доступа к данным в Spring, необходимо использовать один из шаблонов до- ступа к данным, поддерживаемых фреймворком. Посмотрим, как шаблоны Spring могут упростить работу с данными.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии