Jpa EJB-使用EntityManager-查找实体会导致OptimisticLockException吗
不幸的是,我的代码中出现了乐观锁异常,我不知道为什么。也许有人能帮我回答一个一般性的问题 以下场景:Jpa EJB-使用EntityManager-查找实体会导致OptimisticLockException吗,jpa,transactions,ejb,entitymanager,optimistic-locking,Jpa,Transactions,Ejb,Entitymanager,Optimistic Locking,不幸的是,我的代码中出现了乐观锁异常,我不知道为什么。也许有人能帮我回答一个一般性的问题 以下场景: @Entity public class MyEntity { @Id @GeneratedValue private Integer id; @Version private int version; private String value; } @Singleton @TransactionManagement(TransactionM
@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中有另一个线程使用相同的持久性上下文在提交之前更改了我的实体,那么method test()是否会抛出OptimisticLockException,尽管我在method test()中只使用find,不更新任何内容?来自blog
JPA乐观锁定允许任何人读取和更新实体,但是在提交时会进行版本检查,如果自实体读取后数据库中更新了版本,则会引发异常
因此,无需进行更新即可获得OptimaticLockingException。当您阅读myEntity.getVersion()时,假设它=1。如果在提交时(即test()
方法结束时),版本列中的实际值为!=一,
这意味着有人更新了实体(在读取和事务提交之间的平均时间内),因此您刚才读取的值在提交时不再有效。谢谢您的回答!我猜到了,但不确定。博客文章还提到了JPA实体锁定API的附加锁定。我试图找出什么是默认值。有消息称默认设置是不锁定的。如果我现在选择“乐观”,那么使用乐观与否没有区别?因为博客上总是说“提交时进行版本检查”?(我知道,如果我在find()方法中使用它,锁定只针对我定义的实体)这可能取决于提供程序,但我不知道有任何提供程序会检查版本字段以进行乐观锁定,除非要执行更新、删除或插入。“查找”不应导致乐观锁异常,除非存在刷新的实体更改。@Chris您能指出您的源吗?哪一个提供程序仅在一个简单事务的实体已被更新/删除时才进行乐观检查?EclipseLink还将在其他一些情况下进行检查,如合并,但在大多数情况下,乐观锁定应确保在版本不匹配时不会进行写入。乐观锁定的要点是,它确实允许下面的更改,并且只防止直接冲突。检查每个托管实例的版本是否相同,即使它们没有更改,也会降低性能。JPA 2.0允许传递悲观锁定模式来查找将导致版本检查并强制执行OptimisticLockingException的内容,但否则find应仅返回托管实体。您如何获取EntityManager?它们通常不是线程安全的-大多数容器在启动事务时会在代理EM后面获得一个新的EntityManager,因此您可能需要检查配置。