不幸的是,我的代码中出现了一个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()需要一个新的事务。
现在我的问题:如果另一个bean中的另一个线程使用相同的持久化上下文在提交之前更改我的实体,那么方法test()会抛出一个OptimisticLockException,尽管我只使用find并且不在我的方法test()中更新任何东西?
答案 0 :(得分:1)
来自this博客
JPA乐观锁定允许任何人读取和更新实体,但是在提交时进行版本检查,如果在读取实体后数据库中的版本已更新,则抛出异常
因此无需进行更新即可获得OptimisticLockingException。当你阅读它时,假设myEntity.getVersion()== 1。如果在提交时(即当您的test()
方法结束时),版本列中的实际值为!= 1,则会出现OptimisticLockingException。
这意味着有人更新了实体(在READ和事务COMMIT之间的平均时间),因此您刚刚读取的值在提交时不再有效。