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をスローできますが、メソッドtest()ではfindのみを使用し、何も更新しませんが、コミットする前にエンティティを変更しますか?

4

1 に答える 1

1

このブログから

JPA Optimistic Lockingを使用すると、誰でもエンティティを読み取って更新できますが、コミット時にバージョンチェックが行われ、エンティティが読み取られてからデータベースでバージョンが更新された場合は例外がスローされます。

したがって、OptimisticLockingExceptionを取得するために更新を行う必要はありません。あなたがそれを読むとき、myEntity.getVersion()==1と仮定します。test()コミット時(つまり、メソッドが終了したとき)に、バージョン列の実際の値が!= 1の場合、OptimisticLockingExceptionが発生します。

これは、誰かがエンティティを更新したことを意味し(READとトランザクションCOMMITの間の間に)、読み取ったばかりの値はコミット時に無効になります。

于 2013-01-16T20:33:35.900 に答える