Представляю вашему вниманию перевод вторая глава официальной документации Hibernate .
Перевод статьи актуален для версии Hibernate 4.2.19.Final Содержание   2.1. Определение транзакции   2.2. Физические транзакции     2.2.1. Физические транзакции — JDBC     2.2.2. Физические транзакции — JTA     2.2.3. Физические транзакции — CMT     2.2.4. Физические транзакции – прочее     2.2.5. Физические транзакции – устарели   2.3. Использование транзакций Hibernate   2.4. Паттерны транзакций и антипаттерны     2.4.1. Сеансы против шаблонов для каждой операции     2.4.2. Шаблон сеанса на запрос     2.4.3. Разговоры   2.5. Идентификация объекта   2.6. Общие вопросы
2.1. Определение транзакции
Важно понимать, что термин «транзакция» имеет множество значений в отношении персистентности и объектно-реляционной проекции.В большинстве, но не во всех случаях, подходят следующие определения.
Может быть связано с физическими транзакциями базы данных.
Может быть связано с логической концепцией «транзакции» в контексте персистентности.
Может отсылать нас к концепции единицы работы как к четко определенному архитектурному шаблону.
Важный В этой документации логическая и физическая концепции транзакции рассматриваются как одна концепция.
2.2. Физические транзакции
Hibernate использует JDBC API для обеспечения устойчивости.В мире Java существует два четко определенных механизма работы с транзакциями: сам JDBC и JTA. Hibernate поддерживает оба механизма интеграции транзакций и позволяет приложениям управлять физическими транзакциями.
Первое понятие в понимании поддержки транзакций Hibernate — это интерфейс.
org.hibernate.engine.transaction.spi.TransactionFactory , который выполняет две основные функции: Это позволяет Hibernate понимать семантику транзакций текущей среды.
Работаем ли мы сейчас в среде JTA? Активна ли в данный момент физическая транзакция и т. д. Он действует как фабрика экземпляров org.hibernate.Транзакция , используемый приложением для управления и проверки статуса транзакций, org.hibernate.Транзакция – концепция логической транзакции в Hibernate. JPA имеет аналогичную концепцию в интерфейсе.
javax.persistence.EntityTransaction .
Важный javax.persistence.EntityTransaction доступно только при использовании локальных транзакций ресурсов.
Hibernate обеспечивает доступ к org.hibernate.Транзакция независимо от окружающей среды.
org.hibernate.engine.transaction.spi.TransactionFactory – стандартный сервис Hibernate. Подробности см.
в разделы 7.5.16, «org.hibernate.engine.transaction.spi.TransactionFactory» .
2.2.1. Физические транзакции — JDBC
Управление транзакциями с использованием JDBC достигается с помощью методов java.sql.Connection.commit() И java.sql.Connection.rollback() (JDBC не определяет явный метод для инициации транзакции.
) В Hibernate этот подход представлен классом org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
2.2.2. Физические транзакции — JTA
Подход JTA к транзакциям достигается за счет интерфейса javax.transaction.UserTransaction получено от API org.hibernate.service.jta.platform.spi.JtaPlatform .Этот подход представлен классом org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory См.
интеграцию JTA Раздел 7.5.9, «org.hibernate.service.jta.platform.spi.JtaPlatform»
2.2.3. Физические транзакции — CMT
Другой JTA-ориентированный подход к транзакциям использует интерфейс javax.transaction.TransactionManager , полученное из API org.hibernate.service.jta.platform.spi.JtaPlatform .Этот подход представлен классом org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory .
В текущей среде JEE CM доступ к javax.transaction.UserTransaction закрыто.
Важный Термин ШМТ потенциально вводит в заблуждение.
Важная часть заключается в том, что физические транзакции JTA управляются чем-то другим, а не Hibernate API. См.
интеграцию JTA Раздел 7.5.9, «org.hibernate.service.jta.platform.spi.JtaPlatform» .
2.2.4. Физические транзакции – прочее
Также возможно подключение индивидуального решения по управлению транзакциями путем реализации контракта.org.hibernate.engine.transaction.spi.TransactionFactory .
Инициатор службы по умолчанию имеет встроенную поддержку распознавания решений пользователя посредством hibernate.transaction.factory_class , что может указывать: Экопировать org.hibernate.engine.transaction.spi.TransactionFactory .
Имя класса реализации org.hibernate.engine.transaction.spi.TransactionFactory .
Класс реализации должен иметь конструктор без аргументов.
2.2.5. Физические транзакции – устарели
Большинство названных выше классов были перенесены в новые пакеты во время разработки версии 4.0. Чтобы облегчить переход на новую версию, Hibernate на короткое время распознает устаревшие имена.
org.hibernate.transaction.JDBCTransactionFactory нанесено на карту org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
org.hibernate.transaction.JTATransactionFactory нанесено на карту org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory
org.hibernate.transaction.CMTTransactionFactory нанесено на карту org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory
2.3. Использование транзакций Hibernate
Hibernate использует соединения JDBC и ресурсы JTA напрямую, без дополнительной логики синхронизации.Вам важно ознакомиться с JDBC, ANSI SQL и особенностями изоляции транзакций в вашей СУБД.
Hibernate не синхронизирует объекты в памяти.
Поведение, определяемое уровнем изоляции транзакций вашей базы данных, не меняется при использовании Hibernate. Объект org.hibernate.Session действует как кеш, обеспечивающий повторяемые операции чтения и запросы, ограниченные ограничениями транзакций.
Важный Чтобы уменьшить конкуренцию за блокировки, транзакции должны быть как можно более короткими по времени.
Длинные транзакции затрудняют масштабирование вашего приложения до высоких нагрузок.
Транзакции не должны оставаться открытыми, пока конечный пользователь работает; их следует открывать после завершения работы пользователя.
Эту концепцию также называют транзакционной отложенной записью.
2.4. Паттерны транзакций и антипаттерны
2.4.1. Сеансы против шаблонов для каждой операции
Это антипаттерн об открытии и закрытии объекта.Сессия для каждой операции с базой данных в одном потоке.
Это также антипаттерн с точки зрения транзакций базы данных.
Группируйте свои звонки в одну запланированную последовательность.
Кроме того, не следует автоматически фиксировать транзакцию для каждого оператора SQL. Hibernate отключает или ожидает, что сервер приложений немедленно отключит режим автоматической фиксации.
Транзакции базы данных никогда не были чем-то необязательным.
Все взаимодействия с базой данных должны быть заключены в транзакцию.
Избегайте автоматической фиксации при чтении данных, поскольку редко бывает так, что множество небольших транзакций выполняются быстрее, чем одна правильно указанная транзакция.
Кроме того, такое большое количество транзакций сложно поддерживать и расширять.
Важный Использование autocommit не обязательно приводит к использованию транзакций базы данных для каждого выражения.
Вместо этого в режиме автоматической фиксации драйверы JDBC просто выполняют каждый вызов в рамках неявного вызова транзакции.
Это то же самое, как если бы ваше приложение вызывало функцию commit() для транзакции после каждого вызова JDBC.
2.4.2. Шаблон сеанса на запрос
Самый распространенный шаблон транзакции.Термин «запрос» здесь следует понимать в контексте системы, отвечающей на серию запросов от пользователя/клиента.
Веб-приложения являются основным примером таких систем, но, конечно, они не единственные.
Когда начинается обработка запроса, приложение открывает объект Сессия , инициирует транзакцию, выполняет всю связанную работу с данными, завершает транзакцию и закрывает Сессия .
Суть паттерна — это связь «один к одному» между транзакцией и сеансом.
В шаблоне есть общий метод идентификации текущего сеанса, чтобы было проще сообщить об этом.
Сессия между компонентами приложения.
Hibernate обеспечивает поддержку этого метода с помощью метода getCurrentSession() сорт сессионная фабрика .
Понятие «текущего» сеанса должно иметь область действия, определяющую границы, в которых определение «текущего» является истинным.
Это задача договора org.hibernate.context.spi.CurrentSessionContext .
Существует две надежно определенные области: Транзакция JTA, которая может сообщить Hibernate через обратный вызов о завершении, что, в свою очередь, дает возможность завершить текущий сеанс.
Эта стратегия представлена org.hibernate.context.internal.JTASessionContext — выполнение контракта org.hibernate.context.spi.CurrentSessionContext .
Используя эту реализацию, Сессия будет открыт, как только позвонят getCurrentSession() внутри транзакции.
Сам цикл запроса.
Лучший представленный org.hibernate.context.internal.ManagedSessionContext - выполнение контракта org.hibernate.context.spi.CurrentSessionContext .
Существует внешний компонент, отвечающий за управление жизненным циклом и объемом «текущего» сеанса.
На начальном этапе области применения метод связывать() вызванный Контекст управляемой сессии с передачей ссылки на сессию.
В конце метод называется отвязать() .
Важный Метод getCurrentSession() У JTA есть одна неприятная сторона.
Если вы его используете, after_statement Режим освобождения соединения также будет использоваться по умолчанию.
Из-за ограничений JTA Hibernate не может автоматически очистить любой незакрытый экземпляр ScrollableResults или возвращенный Iterator. прокрутка() или итерация() .
Курсоры базы данных освобождаются вызовом ПрокруткаРезультаты.
закрыть() или Hibernate.close(Итератор) явно из раздела «finally».
2.4.3. Диалоги
Шаблон «сеанс на запрос» — не единственное средство проектирования единиц работы.Многие бизнес-процессы требуют серии взаимодействий с пользователем, перемежающихся доступом к базе данных.
В веб-приложениях и корпоративных приложениях недопустимо, чтобы транзакция БД охватывала все взаимодействие с пользователем.
Рассмотрим следующий пример: Процедура 2.1. Пример «долгоиграющего» диалога Откроется первый диалоговый экран.
Данные, отображаемые пользователю, загружаются в отдельный сеанс.
Сессия и транзакции базы данных.
Пользователь может изменять любые поля диалога.
После пяти минут редактирования пользователь использует элемент пользовательского интерфейса для сохранения.
Изменения были отражены в базе данных.
Пользователь также ожидает эксклюзивный доступ к данным на время сеанса редактирования.
Несмотря на то, что у нас есть множественный доступ к базе данных, с точки зрения пользователя эта серия шагов представляет собой одну единицу работы.
Есть много способов реализовать это в приложении.
Первый (наивный) метод — держать сеансы открытыми.
Сессия и транзакции, пока пользователь редактирует, используя механизмы синхронизации базы данных, чтобы гарантировать исключительный доступ пользователя к редактируемым данным и предотвращать доступ к ним других пользователей, обеспечивая изоляцию и атомарность.
Это антишаблон, поскольку избыточная синхронизация является узким местом для проблем с производительностью, возникающих в высоконагруженных приложениях.
Для реализации диалога с базой данных используется ряд транзакций базы данных.
В этом случае обеспечение изоляции бизнес-процессов ложится на плечи приложения.
Один диалог обычно охватывает несколько транзакций.
Множественный доступ к базе данных может быть атомарным, если в базу данных записывается только одна транзакция (обычно последняя).
Все остальные только читают данные.
Типичный путь реализации — создание диалогового окна в стиле мастера, охватывающего несколько этапов цикла запрос/ответ. Hibernate включает в себя некоторые функции, позволяющие реализовать аналогичные функции.
Автоматическое управление версиями Hibernate может управлять параллелизмом за вас.
Он может автоматически определять, являются ли сторонние обновление данных, пока пользователь ожидает. Отдельные объекты Если вы предпочитаете использовать шаблон «сеанс на запрос», все загруженные экземпляры будут отключены, пока пользователь ожидает. Спящий режим позволяет повторно подключиться объекты и сохранить изменения.
Этот шаблон называется сеанс на запрос с отключением объекты.
Автоматическое управление версиями используется для изоляции одновременно выполняемых запросов.
Расширенная сессия Сессия Сессия может быть отключен от базового соединения JDBC после фиксации транзакции базы данных и повторно подключен при возникновении нового клиентского запроса.
Этот шаблон называется сеанс-диалог , что делает повторное присоединение объектов ненужным.
Автоматическое управление версиями используется для изоляции одновременных изменений; сеанс не может быть сброшен автоматически, только явно.
Сеанс на запрос с отдельными объектами И сеанс-диалог есть свои плюсы и минусы.
2.5. Идентификация объекта
Приложение может одновременно получать доступ к одному и тому же постоянному состоянию (строке в базе данных) в двух разных сеансах.Однако экземпляр постоянного класса никогда не используется совместно двумя разными сеансами.
В игру вступают две разные концепции удостоверения: удостоверение БД и удостоверение JVM. Пример 2.1. Идентификатор БД
Пример 2.2. Идентификатор JVMfoo.getId().
equals( bar.getId() )
foo==bar
Для объектов, прикрепленных к одному сеансу Сессия , две концепции идентичности эквивалентны, а идентичность JVM гарантируется идентичностью БД с помощью Hibernate. Приложение может одновременно обращаться к бизнес-объекту с одним и тем же идентификатором БД в двух разных сеансах, при этом оно будет представлено двумя разными экземплярами объектов Java с точки зрения идентификатора JVM. Разрешение конфликтов осуществляется с помощью оптимистической стратегии и автоматического управления версиями во время сброса/фиксации.
Этот подход возлагает ответственность за управление параллелизмом на Hibernate и базу данных.
Это также обеспечивает лучшую масштабируемость, поскольку для гарантии идентичности в однопоточной единице работы не требуются дорогостоящие блокировки.
Приложению не требуется синхронизировать какой-либо бизнес-объект, пока оно выполняется в том же потоке.
Хотя это и не рекомендуется, внутри сеанса приложение может безопасно использовать оператор == для сравнения объектов.
Однако приложение, использующее оператор ==, находится за пределами сеанса.
Сессия может вызвать некоторые проблемы.
Если вы добавите два отдельных экземпляра объекта в один и тот же набор, они могут иметь один и тот же идентификатор базы данных, то есть представлять одну и ту же строку в таблице.
Совсем не гарантируется, что они будут иметь один и тот же идентификатор JVM в отключенном состоянии.
Переопределите методыquals() и hashCode() в постоянных классах, чтобы у них было собственное определение эквивалентности объектов.
Не используйте удостоверение БД для реализации проверки на равенство.
Вместо этого используйте бизнес-ключ, который представляет собой комбинацию уникальных неизменяемых атрибутов.
Идентификатор базы данных может измениться, если объект переходит из переходного состояния в постоянное.
Если временный экземпляр находится вместе с отдельным экземпляром в одном наборе, изменение хеш-кода нарушит контракт набора.
Атрибуты бизнес-ключа могут быть менее стабильными, чем первичные ключи.
Вам нужно только гарантировать стабильность, пока объекты находятся в одном наборе.
Это не проблема Hibernate, поскольку она связана с реализацией идентификации и эквивалентности объектов в Java.
2.6. Общие вопросы
Оба антипаттерна сеанс на пользователя И сеанс для каждого приложения подвержен следующим проблемам.Некоторые из этих проблем также могут возникать в рекомендуемых шаблонах, поэтому сначала убедитесь, что вы понимаете последствия, прежде чем принимать какие-либо проектные решения: Сессия Сессия не является потокобезопасным.
Сущности, работающие параллельно, такие как HTTP-запросы, сессионные компоненты или работники Swing, приведут к состояниям гонки, если сеанс Сессия распределяется между потоками.
Если вы сохраняете сеанс Hibernate в своем сеансе javax.servlet.http.HttpSession (об этом будет сказано позже), вам необходимо рассмотреть вопрос синхронизированного доступа к вашему HttpSession ; в противном случае пользователь, слишком быстро нажимающий кнопку «Обновить», будет использовать один и тот же сеанс в двух параллельных потоках.
Исключение, выдаваемое Hibernate, означает, что вам необходимо отменить транзакцию и немедленно закрыть сеанс (более подробно обсуждается в последующих главах).
Если ваш сеанс ограничен приложением, вам необходимо остановить приложение.
Откат транзакции не приводит к откату бизнес-объектов к состоянию, в котором они находились на момент начала транзакции.
Это означает, что состояние в базе данных и состояние объектов рассинхронизировались.
Обычно это не проблема, поскольку исключения не подлежат восстановлению, и после отката все равно придется начинать заново.
Сеанс кэширует каждый объект, который находится в постоянном состоянии (то есть он отслеживается и проверяется на наличие изменений с помощью Hibernate).
Если вы оставите его на длительный период времени или просто загрузите слишком много данных, он вырастет во много раз, пока вы не получите Исключение OutOfMemoryException .
Есть решение позвонить прозрачный() И выселить() для управления кэшем сеанса Сессия , но вам следует рассмотреть альтернативные способы работы с большими объемами данных, например, хранимые процедуры.
Java не является подходящим инструментом для такого рода операций.
Некоторые решения показаны на Глава 4. Пакетная обработка .
Сеанс, остающийся открытым на протяжении всего сеанса пользователя, также означает высокую вероятность появления «устаревших» данных.
Теги: #hibernate #java #orm #документация #java
-
И Еще О Сортировке
19 Oct, 24 -
Споры О Ценах На Домены.рф
19 Oct, 24 -
Переезд В Армению
19 Oct, 24 -
Республиканская Статистика
19 Oct, 24 -
Встреча - It-Вечеринка
19 Oct, 24