Hibernate如何在提交事务前做乐观锁的行版本检查
How does Hibernate do row version check for Optimistic Locking before committing the transaction
在提交当前事务之前,hibernate 检查行的版本,它应该发出一个 sql select
语句来获取 ithe 行。
假设在发出 select
语句后,hibernate 发现行版本没有改变,因此它应该继续提交事务。
我想知道 hibernate 如何确保在选择行和提交当前事务之间的时间段内没有任何其他事务会更新行以更改其版本号? hibernate 唯一可能做的事情似乎是使用 Select ... For Update
进行悲观锁定的行版本选择或具有这种隔离级别的事务将锁定正在读取的行。
如果我想的是真的:
那么 hibernate 乐观锁定实际上在其操作中使用了悲观锁定,尽管悲观锁定持有时间很短,因为事务将在此之后立即提交。
否则我们在行版本检查和提交之间有一个很短的时间段,可能会出现竞争条件。
请分享您的想法。
对于默认的乐观锁定机制,即@Version
注解给出的机制,没有这种风险。
乐观锁定不需要任何额外的SELECT来获取和检查实体被修改后的版本。因此,涉及两个步骤:
从数据库中获取实体及其版本:
SELECT * FROM PRODUCT WHERE ID = 1;
UPDATE 或 DELETE 将使用与获取实体相同的 SELECT 获取的版本:
UPDATE PRODUCT SET (LIKES, QUANTITY, VERSION) = (5, 10, 3)
WHERE ID = 1 AND VERSION = 2;
因此,Hibernate 不检查实体版本。数据库使用 WHERE 子句对其进行检查。
Hibernate 只检查 PreparedStatement.executeUpdate
方法调用的 updateCount
结果。如果计数不是 updateCount
,则意味着该行已被删除或版本已更改,这意味着我们使用的是陈旧数据,因此将抛出 OptimisticLockException
。
因此,对于默认的基于 @Version
的乐观锁定不会发生冲突,因为一条记录一次只能由一个事务修改,一旦该行被修改锁定,锁将一直保留到事务提交或回滚。
只有明确的 LockModeType.OPTIMISTIC
can lead to race conditions. However, you can easily fix that using a pessimistic shared or explicit lock.
在提交当前事务之前,hibernate 检查行的版本,它应该发出一个 sql select
语句来获取 ithe 行。
假设在发出 select
语句后,hibernate 发现行版本没有改变,因此它应该继续提交事务。
我想知道 hibernate 如何确保在选择行和提交当前事务之间的时间段内没有任何其他事务会更新行以更改其版本号? hibernate 唯一可能做的事情似乎是使用 Select ... For Update
进行悲观锁定的行版本选择或具有这种隔离级别的事务将锁定正在读取的行。
如果我想的是真的:
那么 hibernate 乐观锁定实际上在其操作中使用了悲观锁定,尽管悲观锁定持有时间很短,因为事务将在此之后立即提交。
否则我们在行版本检查和提交之间有一个很短的时间段,可能会出现竞争条件。
请分享您的想法。
对于默认的乐观锁定机制,即@Version
注解给出的机制,没有这种风险。
乐观锁定不需要任何额外的SELECT来获取和检查实体被修改后的版本。因此,涉及两个步骤:
从数据库中获取实体及其版本:
SELECT * FROM PRODUCT WHERE ID = 1;
UPDATE 或 DELETE 将使用与获取实体相同的 SELECT 获取的版本:
UPDATE PRODUCT SET (LIKES, QUANTITY, VERSION) = (5, 10, 3) WHERE ID = 1 AND VERSION = 2;
因此,Hibernate 不检查实体版本。数据库使用 WHERE 子句对其进行检查。
Hibernate 只检查 PreparedStatement.executeUpdate
方法调用的 updateCount
结果。如果计数不是 updateCount
,则意味着该行已被删除或版本已更改,这意味着我们使用的是陈旧数据,因此将抛出 OptimisticLockException
。
因此,对于默认的基于 @Version
的乐观锁定不会发生冲突,因为一条记录一次只能由一个事务修改,一旦该行被修改锁定,锁将一直保留到事务提交或回滚。
只有明确的 LockModeType.OPTIMISTIC
can lead to race conditions. However, you can easily fix that using a pessimistic shared or explicit lock.