从 JPA 悲观锁获取的数据库行上的物理锁

mik*_*ika 1 mysql postgresql concurrency jpa pessimistic-locking

根据 JPA 2.1 规范...

锁定模式PESSIMISTIC_READPESSIMISTIC_WRITE、 和 PESSIMISTIC_FORCE_INCREMENT用于立即获取长期数据库锁定。

我假设悲观锁总是会SELECT ... FOR UPDATE在数据库上触发 SQL,无论使用什么锁模式。现在三个问题:

  1. 这个假设是否正确?如果正确的话,这条规则是否有例外?
  2. 给定一个SELECT ... FOR UPDATE锁定的行。除了锁定行的事务之外,任何其他事务都不能更新锁定的行吗?
  3. 可以通过对事务执行提交或回滚来释放锁。如果应用程序(以及锁定行的事务)突然终止而没有对事务进行提交或回滚,那么锁会发生什么情况?

Ond*_*Mih 6

对于问题1和2,你的假设是正确的:

  1. 是的 - 通常使用悲观锁SELECT ... FOR UPDATE,因为大多数数据库和 JPA 实现仅支持这种类型的锁。在这种情况下,READ 和 WRITE 块之间没有区别,只要两者都表现为 WRITE 锁,JPA 规范就允许这样做。

  2. 是 - 锁定的行不能被任何其他事务修改。如果是写锁(大多数情况下也适用于读锁 - 答案为 1),则在释放锁之前也无法读取锁定的行。请注意,同一表中的其他未锁定行可以自由读取和修改。

同时回答问题3:

  1. 是 - 在提交或回滚的情况下会释放锁。但是,当发生错误、连接断开或事务处理时间过长时,回滚也会自动发生。因此,当应用程序终止时,会立即触发回滚。如果没有,则在超时(通常为 5 分钟)后回滚。