Jpa 如何处理org.eclipse.persistence.exceptions.OptimisticLockExceptio

Jpa 如何处理org.eclipse.persistence.exceptions.OptimisticLockExceptio,jpa,locking,eclipselink,optimistic-locking,optimistic-concurrency,Jpa,Locking,Eclipselink,Optimistic Locking,Optimistic Concurrency,我想通过使用乐观锁定来处理并发执行。我在实体类中包含了@Version注释 在我的代码中,我同时运行两个线程。有时它是正确执行的。有时它会抛出org.eclipse.persistence.exceptions.OptimisticLockException和javax.persistence.OptimisticLockException 公共类StudentCreation实现可运行{ EntityManagerFactory emf= createEntityManagerFactory(

我想通过使用乐观锁定来处理并发执行。我在实体类中包含了
@Version
注释

在我的代码中,我同时运行两个线程。有时它是正确执行的。有时它会抛出
org.eclipse.persistence.exceptions.OptimisticLockException
javax.persistence.OptimisticLockException

公共类StudentCreation实现可运行{
EntityManagerFactory emf=
createEntityManagerFactory(“jpaApp”);
Student=null;
@凌驾
公开募捐{
对于(int i=1;i锁定。学生主键>1
更新时在org.eclipse.persistence.exceptions.OptimisticLockException.ObjectChangedSinceLastReadWhen上(OptimisticLockException.java:144)
位于org.eclipse.persistence.descriptors.VersionLockingPolicy.validateUpdate(VersionLockingPolicy.java:790)
位于org.eclipse.persistence.internal.querys.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1087)
位于org.eclipse.persistence.querys.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:84)
位于org.eclipse.persistence.internal.querys.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
位于org.eclipse.persistence.querys.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
位于org.eclipse.persistence.querys.DatabaseQuery.execute(DatabaseQuery.java:899)
位于org.eclipse.persistence.querys.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
位于org.eclipse.persistence.querys.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
位于org.eclipse.persistence.querys.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
位于org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
位于org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
位于org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737)
位于org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:267)
位于org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:130)
位于org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4207)
位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
位于org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.CommitroTunitOfWork(RepeatableWriteUnitOfWork.java:277)
位于org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
位于org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
在locks.StudentCreation.update(StudentCreation.java:43)
运行(StudentCreation.java:19)
位于java.lang.Thread.run(未知源)

代码> 了解如何处理<代码>优化锁异常>代码>您首先要考虑乐观锁是如何工作的。当使用此策略时,您的实体将获得一个版本字段或属性,该字段被注释为@版本,如果需要的话,您可以将其映射到数据库中的列。默认情况下,当JPA提供者使用乐观锁时,将从数据库中读取实体时@Version字段的值与其当前的值进行比较。当实体中的更改提交到数据库时会发生这种情况,这通常发生在事务结束时。如果@Version字段的旧值等于当前值,则持久性提供器会增加t版本字段。但是,如果它们不匹配,将抛出OptimisticLockException,以指示在您的事务期间,其他事务已更改实体,并且您的事务将回滚。此行为防止您覆盖其他事务的结果。这意味着处理异常的最合适方法是重新执行从数据库中读取实体并重新应用要对其进行的更改。例如,您可以在循环中执行此操作

boolean success = false; 
while (!success) {
    try {
        //start transaction, read entity, update it and commit
        success = true;
    }
    catch (OptimisticLockException ex) {
        //log your error
    }
}

这可确保您的代码尝试重新读取实体并重新对其应用更改,直到没有版本冲突发生且事务成功提交。

问题到底是什么-您希望如何处理这种情况?乐观锁定用于防止覆盖过时数据,因此所有这一切表明它正在工作。