Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate乐观锁机制_Java_Database_Hibernate_Transactions_Optimistic Locking - Fatal编程技术网

Java hibernate乐观锁机制

Java hibernate乐观锁机制,java,database,hibernate,transactions,optimistic-locking,Java,Database,Hibernate,Transactions,Optimistic Locking,我对hibernate乐观锁(专用版本方式)非常好奇,我检查了hibernate源代码,它告诉我在当前事务提交之前检查版本,但是如果在它从DB查询版本列之后发生了另一个事务提交(在很短的时间间隔内),然后当前事务认为没有更改,因此旧事务将被错误地替换 EntityVerifyVersionProcess.java @Override public void doBeforeTransactionCompletion(SessionImplementor session) {

我对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"
            );
        }
    }
这种情况可能吗

希望有DB领域的专家能在这方面帮助我


非常感谢。

快速浏览代码后,
EntityVerifyVersionProcess
用于读取事务,因此不会导致数据丢失。这只会检查事务提交时是否没有返回已经过时的数据。对于
readcommitted
事务,我想这可能会返回立即过时的数据,但如果不详细说明,很难说

另一方面,写事务使用
EntityIncrementVersionProcess
,这是一个完全不同的beast,不存在竞争条件

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源代码使用SQL“从xx选择版本”的方式检查版本更改,而不是在doso中附加“WHERE VERSION=?”子句。它(OptimisticLock)使用“SELECT xxx FOR UPDATE”的方式锁定,而不是在开始时锁定长事务的记录,这很有意义,谢谢你的帮助。不,不。没有选择更新,这将在事务期间锁定记录。只是内部工作并不简单,问题中的代码不处理更新,只处理选择。如果您正在执行更新,则会涉及到其他
*进程
类,但我不太了解内部工作原理,因此无法准确解释流程的运行方式。在内部的某个点上,有
更新foo,其中version=@oldversion
,如果版本增加,它将失败,并避免数据库中任何可能的争用条件。