EJB - Использование EntityManager - Может ли поиск сущности вызвать исключение OptimisticLockException
К сожалению, в моем коде появляется исключение OptimisticLockException, и я не знаю почему. Возможно, есть кто-то, кто может помочь мне с ответом на общий вопрос.
Следующий сценарий:
@Entity
public class MyEntity {
@Id
@GeneratedValue
private Integer id;
@Version
private int version;
private String value;
}
@Singleton
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyBean {
@PersistenceContext
private EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void test() {
MyEntity myEntity = em.find(MyEntity.class, 1);
}
}
CMT используются. Метод test() требует новой транзакции.
Теперь мой вопрос: может ли метод test() вызвать исключение OptimisticLockException, если в другом бине есть другой поток, использующий тот же контекст постоянства, изменяющий мою сущность перед фиксацией, хотя я использую только find и ничего не обновляю в моем методе test()?
1 ответ
Из этого блога
JPA Оптимистическая блокировка позволяет любому читать и обновлять сущность, однако при фиксации выполняется проверка версии, и возникает исключение, если версия была обновлена в базе данных с момента считывания сущности.
Таким образом, нет необходимости делать обновление, чтобы получить OptimisticLockingException. Предположим, что myEntity.getVersion()==1, когда вы читаете это. Вы получите OptimisticLockingException, если при коммите (т.е. когда ваш test()
метод заканчивается), фактическое значение в столбце версии равно!= 1.
Это означает, что кто-то обновил сущность (за время между READ и транзакцией COMMIT), и поэтому значения, которые вы только что прочитали, больше не действительны во время фиксации.