你好,我在使用JPA2中的Optimistic 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);
}
当我意识到出现乐观锁时,我在方法签名中添加了同步关键字以改变两种方法。但是这并没有效果,所以我添加了刷新(entity manager)以确保我拥有当前版本。它也没有任何不同。我还在最后增加了手动刷新,但仍然没有明显改善……
这是方法的最终版本 (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
上调用refresh。
我使用的是eclipselink 2.40。
还有什么可以检查的吗? 目前我已经没有更多的想法了...
Job
吗?你能展示一下Job
中的all
和done
是什么吗? - Serge Ballestajavax.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
- wojtek[com.hg.service.JobServiceImpl$$FastClassByCGLIB$$188a7e8c.invoke(<generated>) at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)]
жҲ‘д»ҘеүҚд»ҺжңӘдҪҝз”ЁиҝҮжӮІи§Ӯй”Ғ...жҳҜеҗҰеҸҜиғҪд»…й’ҲеҜ№дёҖдёӘе®һдҪ“пјҲеңЁиҝҷз§Қжғ…еҶөдёӢдёәJobпјүдҪҝз”Ёе®ғпјҹ - wojtek