Изучаем Java EE 7 - [104]

Шрифт
Интервал

Пессимистическая блокировка

Пессимистическая блокировка основана на предположении, противоположном тому, которое действует для оптимистической блокировки, так как пессимистическая блокировка быстро применяется к сущности до начала операций с ней. Это очень ограничивает ресурсы и приводит к значительному снижению производительности, так как блокировка базы данных поддерживается с использованием SQL-оператора SELECT… FOR UPDATE для чтения данных.

Базы данных обычно предлагают службу для обеспечения пессимистической блокировки. Такая служба позволяет менеджеру сущностей блокировать строку таблицы для предотвращения обновления этой же строки другим потоком. Это эффективный механизм, который гарантирует, что два клиента не смогут одновременно модифицировать одну и ту же строку, однако он требует проведения затратных низкоуровневых проверок в базе данных. Результатом транзакций, которые привели бы к нарушению этого ограничения, стало бы генерирование исключения PessimisticLockException, а эти транзакции были бы помечены как подлежащие откату.

Оптимистическая блокировка целесообразна, когда вы сталкиваетесь с умеренным соперничеством между конкурирующими транзакциями. Однако в некоторых приложениях с более высокой степенью риска соперничества уместнее может оказаться пессимистическая блокировка, поскольку блокировка базы данных применяется незамедлительно в противоположность сбоям оптимистических транзакций, случающимся позднее. Например, во времена экономических кризисов на фондовые рынки поступает огромное количество поручений на продажу. Если одновременно 100 миллионам американцев потребуется продать ценные бумаги, то системе придется прибегнуть к пессимистическим блокировкам для обеспечения согласованности данных. Следует отметить, что в настоящее время рынок настроен довольно пессимистично, а не оптимистично, однако это никак не связано с JPA.

Пессимистическая блокировка может применяться к сущностям, которые не включают аннотированный атрибут @Version.

Жизненный цикл сущности

Вам уже известно большинство секретов сущностей, поэтому взглянем на их жизненный цикл. Созданный (с использованием оператора new) экземпляр сущности виртуальная машина Java рассматривает как простой Java-объект (то есть отсоединенный), который может быть использован приложением в качестве простого объекта. Затем, когда менеджер сущностей обеспечивает постоянство этой сущности, считается, что она находится под управлением. Когда сущность будет находиться под управлением, менеджер сущностей автоматически синхронизирует значения ее атрибутов с основной базой данных (например, если вы измените значение атрибута с помощью метода set, а сущность при этом будет находиться под управлением, то это новое значение окажется автоматически синхронизировано с базой данных).

Чтобы лучше понять этот процесс, взгляните на рис. 6.6, где приведена UML-диаграмма состояний. На ней показаны переходы между всеми состояниями сущности Customer.


Рис. 6.6. Жизненный цикл сущности


Чтобы создать экземпляр сущности Customer, вы используете оператор new. Этот объект затем располагается в памяти, хотя JPA ничего о нем не знает. Если вы не станете что-либо делать с объектом, то он окажется вне области видимости и в итоге будет удален при сборке мусора, что станет концом его жизненного цикла. Далее вы можете обеспечить постоянство Customer с помощью метода EntityManager.persist(). В тот момент сущность оказывается под управлением, а ее состояние синхронизируется с базой данных. Пока сущность пребывает в этом состоянии, в котором она подвергается управлению, вы можете обновить атрибуты с использованием методов-сеттеров (например, customer.setFirstName()) или обновить содержимое с помощью метода EntityManager.refresh(). Все эти изменения будут синхронизированы между сущностью и базой данных. Если вы вызовете метод EntityManager.contains(customer), пока сущность пребывает в этом состоянии, то он возвратит true, поскольку сущность Customer содержится в контексте постоянства (то есть находится под управлением).

Сущность также может оказаться под управлением при загрузке из базы данных. Когда вы используете метод EntityManager.find() или генерируете JPQL-запрос для извлечения списка сущностей, все сущности автоматически подвергаются управлению и вы можете начать обновлять или удалять их атрибуты.

Пока сущность пребывает в состоянии, в котором она подвергается управлению, вы можете вызвать метод EntityManager.remove(), в результате чего эта сущность окажется удалена из базы данных и больше не будет находиться под управлением. Однако Java-объект продолжит располагаться в памяти, и вы все еще сможете использовать его до тех пор, пока сборщик мусора не избавится от этого объекта.

Теперь взглянем на состояние, в котором сущность является отсоединенной. Вы уже видели в предыдущей главе, как явный вызов метода EntityManager.clear() или EntityManager.detach(customer) приводит к удалению сущности из контекста постоянства; она оказывается отсоединенной. Однако есть другой, более тонкий способ отсоединить сущность: ее сериализация.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.