【发布时间】:2014-09-01 19:28:21
【问题描述】:
您好,我正在为 JPA2 上的 Optimistick Lock 苦苦挣扎,我不知道为什么会发生这种情况。 我的情况是我正在运行多个线程,但数据库中有一个实体存储进度。这意味着不同的线程在执行期间尝试更新此实体,以便可以查看用户的进度。
我有一个方法addAllItems 和addDone。这两种方法都用于通过多个线程更新实体,我通过显示(done/allItems)*100 来显示结果。
方法一开始很简单
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void addAllItems(Long id, Integer items){
Job job = jobDao.findById(id);
job.setAll(job.getAll() + items);
jobDao.merge(job);
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void addDone(Long id, Integer done){
Job job = jobDao.findById(id);
job.setDone(job.getDone() + done);
jobDao.merge(job);
}
当我意识到 Optimistic Lock 正在发生时,我通过在签名中添加同步来更改这两种方法。它没有效果,所以我添加了刷新(来自实体管理器)以确保我拥有当前版本。它也没有任何区别。最后我还添加了手动冲洗,但仍然没有更好的...
这里是方法的最终版本(addAllItems 几乎相同,只是在 setter 中有所不同):
@Transactional(propagation=Propagation.REQUIRES_NEW)
public synchronized void addDone(Long id, Integer done){
Job job = jobDao.findById(id);
job = jobDao.refresh(job);
job.setDone(job.getDone() + done);
jobDao.merge(job);
jobDao.flush();
}
jobDao.refresh 方法只是在 entityManager 上调用刷新。
我正在使用 eclipselink 2.40。
我还能检查什么? 我暂时没有想法......
【问题讨论】:
-
我正在努力,但截止日期非常接近,所以我正在寻找更有经验的人的帮助。我认为这就是创建 stackoverflow 的原因。如果您不想回答,请不要回答。
-
或许你应该对工作使用悲观锁?
-
错误发生在哪个实体上?真的
Job吗?你能在Job中显示什么是all和done -
@SergeBallesta Job 实体发生错误。 all 和 done 只是整数。这是一条日志行:
javax.persistence.OptimisticLockException: Exception [EclipseLink-5006] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.OptimisticLockException Exception Description: The object [com.hg.entity.Job@98] cannot be updated because it has changed or been deleted since it was last read. Class> com.hg.entity.Job Primary Key> 152 -
您应该首先确保您确实使用了事务代理(查看堆栈跟踪),然后使用悲观锁
标签: java spring eclipselink jpa-2.0 optimistic-locking