【问题标题】:JPA - Pessimistic Lock - What happens when the lock exists?JPA - 悲观锁 - 当锁存在时会发生什么?
【发布时间】:2015-02-03 17:14:06
【问题描述】:
背景信息:
我有一个问题是实体更新未通过的症状。查看我的日志,我可以看到我预期的更新 sql 语句,但它们几乎是同时的(相隔 0.012 秒),并且应用程序在更新实体时使用了悲观读取锁。
这引出了我的问题:
当存在悲观锁时,预期的行为是什么?我还应该期待看到多个更新查询吗?我应该期望抛出 PessimisticLockException ,对吗?我还应该寻找其他指标吗?
Hibernate 是我的 JPA 实现。
【问题讨论】:
标签:
java
hibernate
jpa
locking
【解决方案1】:
悲观锁实际上是使用 SQL 查询传播到数据库级别的(检查执行的查询以进行比较)。
如果存在悲观锁,应用程序应该等待 DB 直到锁被释放,因此抛出异常不是强制性的(但可以)。
现在关于例外情况:
/*
PessimisticLockException if pessimistic locking fails and the transaction is rolled back
LockTimeoutException if pessimistic locking fails and only the statement is rolled back
*/
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode);
对于其他 EntityManager 方法,这两个异常会在类似的情况下引发。
【解决方案2】:
悲观锁定防止对象被同时更新。相反,对象的更新正在形成某种链——如果锁已经存在,更新将等到锁被释放。
因此,抛出异常不是悲观锁的预期结果。预期的行为是消除我上面描述的并发性。
如需进一步阅读,您可以参考this 和this 来源。
在我们的例子中,您的更新似乎没有通过,因为它被稍后的更新覆盖。