JPA - 悲观锁 - 当锁存在时会发生什么?

JPA - Pessimistic Lock - What happens when the lock exists?

背景信息: 我遇到的问题是实体更新未通过的症状。查看我的日志,我可以看到我预期的更新 sql 语句,但它们几乎是同时发生的(相隔 0.012 秒)并且应用程序在更新实体时使用悲观读锁。

这引出了我的问题: 存在悲观锁时的预期行为是什么?我还应该期望看到多个更新查询吗?我应该期望 PessimisticLockException 被抛出,对吧?我还应该寻找其他指标吗?

Hibernate 是我的 JPA 实现。

悲观锁实际上使用SQL查询传播到数据库级别(检查已执行的查询以进行比较)。 如果存在悲观锁,应用程序应该等待数据库直到锁被释放,因此抛出异常不是强制性的(但它可能是)。

现在关于例外情况:

/*
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 方法,这两个异常会在类似情况下抛出。

悲观锁定防止对象被同时更新。相反,对象的更新正在形成某种链 - 如果锁已经存在,更新将等到锁被释放。

因此,抛出异常不是悲观锁的预期结果。预期的行为是消除我上面描述的并发。

如需进一步阅读,您可以参考 this and this 来源。

在我们的例子中,您的更新似乎没有通过,因为它被后来的更新覆盖了。