Метод | Описание |
---|---|
Выполняет поиск сущности указанного класса и первичного ключа, а затем блокирует ее согласно заданному типу режима блокировки | |
void lock(Object entity, LockModeType lockMode) | Блокирует экземпляр сущности, который содержится в контексте постоянства, согласно заданному типу режима блокировки |
void refresh(Object entity, LockModeType lockMode) | Обновляет состояние экземпляра из базы данных, перезаписывая изменения, внесенные в сущность, при наличии таковых, и блокирует ее согласно заданному типу режима блокировки |
LockModeType getLockMode(Object entity) | Извлекает значение текущего режима блокировки для экземпляра сущности |
Метод | Описание |
---|---|
LockModeType getLockMode() | Извлекает значение текущего режима блокировки для запроса |
Query setLockMode(LockModeType lockMode) | Задает тип режима блокировки для использования при выполнении запроса |
Каждый из этих методов принимает LockModeType в качестве параметра, который, в свою очередь, может хранить разные значения:
• OPTIMISTIC — применяет оптимистическую блокировку;
• OPTIMISTIC_FORCE_INCREMENT — применяет оптимистическую блокировку и форсирует инкрементирование значения столбца version, связанного с сущностью (см. следующий подраздел «Контроль версий»);
• PESSIMISTIC_READ — применяет пессимистическую блокировку без необходимости в повторном чтении данных в конце транзакции для обеспечения блокировки;
• PESSIMISTIC_WRITE — применяет пессимистическую блокировку и форсирует сериализацию между транзакциями, которые пытаются обновить сущность;
• PESSIMISTIC_FORCE_INCREMENT — применяет пессимистическую блокировку и форсирует инкрементирование значения столбца version, связанного с сущностью (см. подраздел «Контроль версий» далее);
• NONE — определяет, что не должен использоваться никакой механизм блокировки.
Вы можете задавать эти параметры во многих местах в зависимости от того, как необходимо указать блокировки. Вы можете обеспечить чтение, а
Book book = em.find(Book.class, 12);
// Блокировать, чтобы повысить цену
em.lock(book, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
book.raisePriceByTwoDollars();
Либо вы можете обеспечить чтение
Book book = em.find(Book.class, 12, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
// Блокировка уже применена к сущности Book, повысить цену
book.raisePriceByTwoDollars();
Конкурентный доступ и блокировки являются ключевыми мотиваторами для контроля версий.
Контроль версий
В случае со спецификациями Java применяется контроль версий: Java SE 5.0, Java SE 6.0, EJB 3.1, JAX-RS 1.0 и т. д. При выходе новой версии JAX-RS ее номер увеличивается и вы переходите на JAX-RS 1.1. JPA использует этот точный механизм, когда вам необходимо присвоить номера версий сущностям. Таким образом, когда вы в первый раз обеспечите постоянство сущности в базе данных, она получит номер версии, равный 1. Позднее, если вы обновите атрибут и зафиксируете это изменение в базе данных, номер версии сущности будет равен уже 2 и т. д. Номер версии будет модифицироваться при каждом внесении изменений в сущность.
Чтобы это происходило, у сущности должен иметься атрибут для сохранения номера версии, снабженный аннотацией @Version. Он в дальнейшем отображается в столбец в базе данных. К числу типов атрибутов, поддерживающих контроль версий, относятся int, Integer, short, Short, long, Long и Timestamp. В листинге 6.36 показано, как добавить атрибут version в код сущности Book.
@Entity
public class Book {
··@Id @GeneratedValue
··private Long id;
··@Version