我对JPA中的LockModeTypes的工作感到困惑:
LockModeType.Optimistic
LockModeType.OPTIMISTIC_FORCE_INCREMENT
即使未更新实体,它也会在此处增加版本列。
LockModeType
LockModeType.PESSIMISTIC_READ
此锁定模式发出a select for update nowait(如果未指定提示超时)。
select for update nowait
Read
LockModeType.PESSIMISTIC_WRITE
此锁定模式还会发出一个select for update nowait(如果未指定提示超时)。
LockModeType.PESSIMISTIC_FORCE_INCREMENT
这样做select for update nowait(如果未指定提示超时),并且还会增加版本号。
for update no wait
首先,我将区分乐观锁和悲观锁,因为它们的底层机制不同。
乐观锁定完全由JPA控制,并且仅需要数据库表中的附加版本列。它完全独立于用于存储关系数据的基础数据库引擎。
另一方面,悲观锁定使用基础数据库提供的锁定机制来锁定表中的现有记录。JPA需要知道如何触发这些锁定,并且某些数据库不支持或仅部分支持它们。
现在到锁类型列表:
LockModeType lockMode = resolveLockMode(); A a = em.find(A.class, 1, lockMode);
此模式与相似LockModeType.PESSIMISTIC_WRITE,但有一点不同:在通过某种事务在同一实体上施加写锁定之前,它不应阻止读取实体。它还允许使用锁定其他事务LockModeType.PESSIMISTIC_READ。WRITE和READ锁之间的区别在这里(ObjectDB)和这里(OpenJPA)都有很好的解释。如果一个实体已经被另一个事务锁定,则对其进行任何锁定尝试都将引发异常。可以将此行为修改为在引发异常并回滚事务之前等待一段时间以释放锁。为此,javax.persistence.lock.timeout请在引发异常之前指定提示以毫秒为单位。有多种方法可以在多个级别上执行此操作,如Java EE教程。
javax.persistence.lock.timeout
这是的更强版本LockModeType.PESSIMISTIC_READ。当WRITE锁定到位时,JPA在数据库的帮助下将阻止任何其他事务读取实体,而不仅仅是像READ锁定时一样进行写入。
WRITE
READ
SELECT...FOR UPDATE
这是另一种很少使用的锁定模式。但是,这是您需要结合使用PESSIMISTIC和OPTIMISTIC机制的一种选择。PESSIMISTIC_WRITE在以下情况下,使用Plain 将失败:
PESSIMISTIC
OPTIMISTIC
PESSIMISTIC_WRITE
OptimisticLockException
LockModeType.NONE
如果实体不提供版本字段,则为默认设置。这意味着没有启用锁定,将尽力解决冲突,并且不会检测到冲突。这是事务外部唯一允许的锁定模式