Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Режимы блокировки

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

Использование режимов оптимистичной блокировки заставляет persistence provider проверять атрибуты версии для сущностей, которые были прочитаны (но не изменены) во время транзакции, а также для сущностей, которые были обновлены.

Использование режимов пессимистичной блокировки указывает, что persistence provider должен немедленно получить долгосрочные блокировки чтения или записи данных базы данных, соответствующих объекту сущности.

Вы можете установить режим блокировки для операции с объектом сущности, указав один из режимов блокировки, определённых в перечислимом типе javax.persistence.LockModeType, указанном в таблице 45-1.

Таблица 45-1. Режимы блокировки для параллельного доступа к объекту

Режим блокировки

Описание

OPTIMISTIC

Получение оптимистичной блокировки чтения для всех сущностей с атрибутами версии.

OPTIMISTIC_FORCE_INCREMENT

Получение оптимистичной блокировки чтения для всех объектов с атрибутами версии и увеличение значения атрибута версии.

PESSIMISTIC_READ

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

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

PESSIMISTIC_WRITE

Немедленное получение долговременной блокировки записи данных, чтобы предотвратить чтение, изменение или удаление данных.

PESSIMISTIC_FORCE_INCREMENT

Немедленное получение долговременной блокировки данных, чтобы предотвратить изменение или удаление данных, и увеличение атрибута версии у версионных сущностей.

READ

Синоним для OPTIMISTIC. Использование LockModeType.OPTIMISTIC предпочтительнее для новых приложений.

WRITE

Синоним для OPTIMISTIC_FORCE_INCREMENT. Использование LockModeType.OPTIMISTIC_FORCE_INCREMENT предпочтительнее для новых приложений.

NONE

Никакой дополнительной блокировки не произойдёт с данными в базе данных.

Установка режима блокировки

Чтобы указать режим блокировки, используйте один из следующих методов:

  1. Вызовите метод EntityManager.lock, перейдя в один из режимов блокировки:

    EntityManager em = ...;
    Person person = ...;
    em.lock(person, LockModeType.OPTIMISTIC);
  2. Вызовите один из методов EntityManager.find, которые принимают режим блокировки в качестве параметра:

    EntityManager em = ...;
    String personPK = ...;
    Person person = em.find(Person.class, personPK,
        LockModeType.PESSIMISTIC_WRITE);
  3. Вызовите один из методов EntityManager.refresh, которые принимают режим блокировки в качестве параметра:

    EntityManager em = ...;
    String personPK = ...;
    Person person = em.find(Person.class, personPK);
    ...
    em.refresh(person, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
  4. Вызовите метод Query.setLockMode или TypedQuery.setLockMode, передав режим блокировки в качестве параметра:

    Query q = em.createQuery(...);
    q.setLockMode(LockModeType.PESSIMISTIC_FORCE_INCREMENT);
  5. Добавьте элемент lockMode в аннотацию @NamedQuery:

    @NamedQuery(name="lockPersonQuery",
      query="SELECT p FROM Person p WHERE p.name LIKE :name",
      lockMode=PESSIMISTIC_READ)

Использование пессимистичной блокировки

Версионные объекты, а также объекты, которые не имеют атрибутов версии, могут быть заблокированы пессимистично.

Чтобы блокировать объекты пессимистично, установите режим блокировки на PESSIMISTIC_READ, PESSIMISTIC_WRITE или PESSIMISTIC_FORCE_INCREMENT.

Если пессимистичная блокировка не может быть получена для записей базы данных и неудачная блокировка данных приводит к откату транзакции, генерируется PessimisticLockException. Если пессимистичная блокировка не может быть получена, но сбой блокировки не приводит к откату транзакции, выдаётся LockTimeoutException.

Пессимистичная блокировка версионного объекта с помощью PESSIMISTIC_FORCE_INCREMENT приводит к увеличению атрибута версии, даже если данные объекта не изменены. При пессимистичной блокировке версионного объекта persistence provider будет выполнять проверки версий, которые происходят во время оптимистичной блокировки, и в случае сбоя проверки версии будет выдано OptimisticLockException. Попытка заблокировать неверсионную сущность с помощью PESSIMISTIC_FORCE_INCREMENT не переносима и может привести к PersistenceException, если persistence provider не поддерживает оптимистичных блокировок для неверсионных сущностей. Блокировка версионного объекта с помощью PESSIMISTIC_WRITE приводит к увеличению атрибута версии, если транзакция была успешно зафиксирована.

Тайм-ауты пессимистичной блокировки

Используйте свойство javax.persistence.lock.timeout, чтобы указать интервал времени в миллисекундах, который persistence provider должен ждать, чтобы получить блокировку таблиц базы данных. Если время, необходимое для получения блокировки, превышает значение этого свойства, будет выброшено LockTimeoutException, но текущая транзакция не будет помечена для отката. Если для этого свойства установлено значение 0, persistence provider должен выдать LockTimeoutException, если он не может немедленно получить блокировку.

Примечание:

Переносимые приложения не должны полагаться на настройку javax.persistence.lock.timeout, поскольку стратегия блокировки и настройки базы данных могут сделать настройки тайм-аута недействительными. Значение javax.persistence.lock.timeout является подсказкой, а не контрактом.

Это свойство можно установить программно, передав его методам EntityManager-а, которые позволяют указывать режимы блокировки: методы Query.setLockMode и TypedQuery.setLockMode, аннотация @NamedQuery и метод Persistence.createEntityManagerFactory. Оно также может быть установлено как свойство в дескрипторе развёртывания persistence.xml.

Если javax.persistence.lock.timeout установлен в нескольких местах, значение будет определено в следующем порядке:

  1. Аргумент одного из методов EntityManager или Query

  2. Параметр в аннотации @NamedQuery

  3. Аргумент метода Persistence.createEntityManagerFactory

  4. Значение в дескрипторе развёртывания persistence.xml


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)