在提交当前事务之前,hibernate 检查行的版本时,应该发出 sql select
用于获取行的语句。
假设在发出 select
之后语句 hibernate 发现行版本没有改变,因此它应该继续提交事务。
我想知道 hibernate 如何确保在选择行和提交当前事务之间的时间段内没有任何其他事务会更新行更改其版本号? hibernate 可以做的唯一可能的事情似乎是使用 Select ... For Update
进行悲观锁定的行版本选择。或者具有这种隔离级别的事务将锁定正在读取的行。
如果我的想法是真的:
请分享您的想法。
最佳答案
对于默认的乐观锁机制,由 @Version
给出的机制。注释,没有这种风险。
乐观锁定不需要任何额外的 SELECT 来获取和检查实体修改后的版本。因此,涉及两个步骤:
SELECT * FROM PRODUCT WHERE ID = 1;
UPDATE PRODUCT SET (LIKES, QUANTITY, VERSION) = (5, 10, 3)
WHERE ID = 1 AND VERSION = 2;
因此,Hibernate 不会检查实体版本。 DB 使用 WHERE 子句对其进行检查。
Hibernate 只检查
updateCount
PreparedStatement.executeUpdate
的结果方法调用。如果计数不是 updateCount
,这意味着该行已被删除或版本已更改,这意味着我们正在使用陈旧数据,因此 OptimisticLockException
将被抛出。因此,默认值
@Version
不会发生冲突。基于乐观锁,因为一条记录一次只能被一个事务修改,一旦行被修改锁定,锁将一直保持到事务提交或回滚。只有显式
LockModeType.OPTIMISTIC
可能导致竞争条件。但是,您可以轻松地fix that using a pessimistic shared or explicit lock .
关于sql - Hibernate 如何在提交事务之前对乐观锁进行行版本检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52988292/