2

不幸的是,我的代码中出现了 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() 中的任何内容?

4

1 回答 1

1

这个博客

JPA 乐观锁定允许任何人读取和更新实体,但是在提交时会进行版本检查,如果在读取实体后在数据库中更新了版本,则会引发异常

因此无需进行更新即可获得 OptimisticLockingException。当您阅读它时假设 myEntity.getVersion()==1 。test()如果在提交时(即您的方法结束时),版本列中的实际值为 != 1 ,您将收到 OptimisticLockingException 。

这意味着有人更新了实体(在 READ 和事务 COMMIT 之间的平均时间),因此您刚刚读取的值在提交时不再有效。

于 2013-01-16T20:33:35.900 回答