简体   繁体   English

休眠乐观锁定机制

[英]hibernate optimistic lock mechanism

I am so curious about the hibernate optimistic lock (dedicated version way), I checked hibernate source code which tells that it checks version before current transaction commits, but if there is another transaction happens to committed after it query the version column from DB(in a very short time gap), then current transaction considers there is no change, so the old transaction would be replaced wrongly. 我对休眠乐观锁(专用的版本方式)很好奇,我检查了休眠源代码,该代码告诉它在当前事务提交之前检查版本,但是在从数据库查询版本列后是否还有其他事务提交了( (很短的时间间隔),那么当前交易会认为没有变化,因此旧交易将被错误地替换。

EntityVerifyVersionProcess.java 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"
            );
        }
    }

is such case possible? 这样的情况可能吗?

Hope there are DB domain experts who would help me on this. 希望有数据库领域的专家可以帮助我。

Many thanks. 非常感谢。

Based on a quick glance of the code, EntityVerifyVersionProcess is used for read transactions, so there's no potential for data loss involved. 快速浏览一下代码, EntityVerifyVersionProcess用于读取事务,因此不存在丢失数据的潜在可能。 This would only check that when the transaction commits, it's not returning data that's already stale. 这只会检查事务提交时是否没有返回已经过时的数据。 With a READ COMMITTED transaction, I suppose this might return data that is instantly going stale, but hard to say without going into details. 对于READ COMMITTED事务,我想这可能返回立即过时的数据,但是如果不进行详细说明就很难说。

Write transactions on the other hand use EntityIncrementVersionProcess , which is a completely different beast and leaves no chance for race conditions. 另一方面,使用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 );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM