首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JPA2优化锁

JPA2优化锁
EN

Stack Overflow用户
提问于 2014-09-02 03:28:22
回答 1查看 730关注 0票数 3

嗨,我正在和JPA2上的Optimistick作斗争,我不知道为什么会发生这种情况。我的情况是,我正在运行多个线程,但在DB中有一个存储进度的实体。这意味着不同的线程在执行期间试图更新这个实体,以便能够按用户查看进度。

我有一个方法addAllItemsaddDone。这两种方法都用于通过多个线程更新实体,我通过显示(done/allItems)*100来显示结果。

开始的时候方法很简单

代码语言:javascript
复制
@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):

代码语言:javascript
复制
@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。

我还可以检查什么?我现在没主意了.

EN

回答 1

Stack Overflow用户

发布于 2014-09-02 22:57:53

由于您确定您正在使用代理(我假设您正确配置了PlatformTransactionManager),您可以尝试在事务中使用显式悲观锁-通常您不需要这样做,但如果它修复了问题...

我猜想在你的道里,你应该有这样的东西:

代码语言:javascript
复制
Job job = EntityManager.find(Job.class, jobId);

要强制使用悲观锁,只需将其更改为:

代码语言:javascript
复制
Job job = EntityManager.find(Job.class, jobId, LockModeType.PESSIMISTIC_WRITE);

由于您只是执行加载、修改、存储和提交,因此这可能是悲观锁定的正确用例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25611942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档