我对休眠乐观锁(专用的版本方式)非常好奇,我检查了休眠源代码,该代码告诉它在当前事务提交之前检查版本,但是在从数据库查询版本列后是否有其他事务提交了(时间间隔非常短),那么当前交易会认为没有变化,因此旧交易将被错误地替换。

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用于读取事务,因此不会造成数据丢失。这只会检查在事务提交时是否没有返回已经过时的数据。对于READ COMMITTED事务,我想这可能返回立即过时的数据,但是如果不进行详细说明就很难说。

另一方面,使用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 );
}

07-24 09:30