嗨,我正在和JPA2上的Optimistick作斗争,我不知道为什么会发生这种情况。我的情况是,我正在运行多个线程,但在DB中有一个存储进度的实体。这意味着不同的线程在执行期间试图更新这个实体,以便能够按用户查看进度。
我有一个方法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);
}当我意识到乐观锁正在发生时,我更改了这两种方法,将synchronized添加到签名中。它没有效果,所以我添加了刷新(从实体管理器),以确保我有最新的版本。这也没有什么不同。我还在最后添加了手动冲洗,但仍然没有更好的……
以下是方法的最终版本(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。
我还可以检查什么?我现在没主意了.
发布于 2014-09-02 22:57:53
由于您确定您正在使用代理(我假设您正确配置了PlatformTransactionManager),您可以尝试在事务中使用显式悲观锁-通常您不需要这样做,但如果它修复了问题...
我猜想在你的道里,你应该有这样的东西:
Job job = EntityManager.find(Job.class, jobId);要强制使用悲观锁,只需将其更改为:
Job job = EntityManager.find(Job.class, jobId, LockModeType.PESSIMISTIC_WRITE);由于您只是执行加载、修改、存储和提交,因此这可能是悲观锁定的正确用例。
https://stackoverflow.com/questions/25611942
复制相似问题