EntityManager:设置LockModeType.PESSIMISTIC_WRITE似乎不要执行锁定

时间:2014-10-03 14:25:44

标签: jpa locking java-ee-7

我正在使用JPA(Hibernate)和Postgresql开发在Wildfly 8.1.0上运行的Java EE应用程序。我有传入的REST请求,这些请求可以并行地异步收入。

我有一个REST函数“递减”,除了其他东西之外,还会减少数据库中给定数量的值。所以这个功能需要  1)检索数据集(使用EntityManager)  2)从实体中读取值成员  3)减少该值  4)将其存储在实体中  5)保存此数据集(em.merge)

我需要一个锁定机制来锁定读取我的值,只要先前的读取值没有递减并存储回来(否则两个并行请求将读取相同的值,减少它并将其存储回来) 所以我在步骤1)和2)之间放置了em.lock(<entity>, LockModeType.PESSIMISTIC_WRITE)

然而,它似乎并没有解决我的矛盾问题。如果我运行一些并行测试循环,它请求我的减量方法(通过REST),我可以看到我没有那么多的减量,因为我有调用 - 即使使用em.lock。

好吧,如果我没有在<property name="javax.persistence.lock.timeout" value="1000"/>中设置persistence.xml,我会在开始第二个测试循环后得到很多LockTimeoutExceptions,这表明已经设置了锁。

可能有什么不对? - 提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

使用乐观锁:

@Entity
public class MyEntity implements Serializable {
  @Version
  private long optimisticLockField; //will be under the management of the lock, do not modify

  ... other entity fields

}

答案 1 :(得分:0)

最后,我找到了一个解决这个问题的简单方法:我在查询中做了减量,例如。

UPDATE Account a SET a.balance = a.balance - :value WHERE a = :account

当然,如果需要,我们也可以进行限制检查,例如确保余额永远不会消极......

UPDATE Account a SET a.balance = a.balance - :value WHERE a = :account AND a.balance >= :value