简体   繁体   中英

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

@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. 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.

Write transactions on the other hand use EntityIncrementVersionProcess , which is a completely different beast and leaves no chance for race conditions.

public void doBeforeTransactionCompletion(SessionImplementor session) {
    final EntityPersister persister = entry.getPersister();
    final Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
    entry.forceLocked( object, nextVersion );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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