hibernate乐观锁机制
hibernate optimistic lock mechanism
我对hibernate乐观锁(专用版本方式)非常好奇,我检查了hibernate源代码,它告诉它在当前事务提交之前检查版本,但是如果在它查询版本之后恰好有另一个事务提交来自DB的列(在很短的时间间隔内),然后当前事务认为没有变化,因此旧事务将被错误地替换。
EntityVerifyVersionProcess.java
@Override
public void doBeforeTransactionCompletion(SessionImplementor session) {
final EntityPersister persister = entry.getPersister();
if ( !entry.isExistsInDatabase() ) {
// HHH-9419: We cannot check for a version of an entry we ourselves deleted
return;
}
final Object latestVersion = persister.getCurrentVersion( entry.getId(), session );
if ( !entry.getVersion().equals( latestVersion ) ) {
throw new OptimisticLockException(
object,
"Newer version [" + latestVersion +
"] of entity [" + MessageHelper.infoString( entry.getEntityName(), entry.getId() ) +
"] found in database"
);
}
}
这种情况可能吗?
希望有数据库领域的专家能帮我解决这个问题。
非常感谢。
根据对代码的快速浏览,EntityVerifyVersionProcess
用于读取事务,因此不存在数据丢失的可能性。这只会检查当事务提交时,它不是 returning 已经过时的数据。对于 READ COMMITTED
事务,我想这个 可能 return 数据会立即过时,但如果不深入细节就很难说。
另一方面,使用 EntityIncrementVersionProcess
编写事务,这是一种完全不同的野兽,没有机会出现竞争条件。
public void doBeforeTransactionCompletion(SessionImplementor session) {
final EntityPersister persister = entry.getPersister();
final Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
entry.forceLocked( object, nextVersion );
}
我对hibernate乐观锁(专用版本方式)非常好奇,我检查了hibernate源代码,它告诉它在当前事务提交之前检查版本,但是如果在它查询版本之后恰好有另一个事务提交来自DB的列(在很短的时间间隔内),然后当前事务认为没有变化,因此旧事务将被错误地替换。
EntityVerifyVersionProcess.java
@Override
public void doBeforeTransactionCompletion(SessionImplementor session) {
final EntityPersister persister = entry.getPersister();
if ( !entry.isExistsInDatabase() ) {
// HHH-9419: We cannot check for a version of an entry we ourselves deleted
return;
}
final Object latestVersion = persister.getCurrentVersion( entry.getId(), session );
if ( !entry.getVersion().equals( latestVersion ) ) {
throw new OptimisticLockException(
object,
"Newer version [" + latestVersion +
"] of entity [" + MessageHelper.infoString( entry.getEntityName(), entry.getId() ) +
"] found in database"
);
}
}
这种情况可能吗?
希望有数据库领域的专家能帮我解决这个问题。
非常感谢。
根据对代码的快速浏览,EntityVerifyVersionProcess
用于读取事务,因此不存在数据丢失的可能性。这只会检查当事务提交时,它不是 returning 已经过时的数据。对于 READ COMMITTED
事务,我想这个 可能 return 数据会立即过时,但如果不深入细节就很难说。
另一方面,使用 EntityIncrementVersionProcess
编写事务,这是一种完全不同的野兽,没有机会出现竞争条件。
public void doBeforeTransactionCompletion(SessionImplementor session) {
final EntityPersister persister = entry.getPersister();
final Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
entry.forceLocked( object, nextVersion );
}