You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7升级至3.3后,新事务内查询获取实体时乐观锁失效问题求助

Spring Boot 2.7升级至3.3后,新事务内查询获取实体时乐观锁失效问题求助

最近我把项目从Spring Boot 2.7升级到3.3后,遇到了一个乐观锁的异常问题——当在新事务中从数据库查询获取实体时,乐观锁完全不生效了,具体场景如下:

@Entity
class MyEntity{
    @Id
    long id;
    
    @Version
    Long version;
}

class A {
    private B bService;

    @Transactional(readOnly = true)
    public void execute() {
        try {
            bService.begin(10);
        } catch (OptimisticLockingFailureException e) {
            log.... // 在Spring 3.3中这段代码从未触发过
        }
}

class B {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public MyEntity begin(Long id) {
        MyEntity freshMyEntity = repository.findAwaiting(id)
                .orElseThrow(EntityNotFoundException::new);

// 此时另一个事务提交了同ID的实体
// 或者我在这里手动暂停,然后在数据库中手动提交修改
// 两种情况都会导致数据库里的version字段被递增
        return repository.save(freshMyEntity);
    }
}

奇怪的是,如果我移除repository.findAwaiting查询操作,让实体作为参数直接传入begin方法,乐观锁就可以正常工作。我是不是漏掉了什么配置?这看起来像是个bug,但我不确定是不是自己理解错了?

EDIT 1:我的预期行为
我原本以为begin方法里的save操作应该抛出异常,因为此时另一个事务已经修改了同ID实体的version字段,但实际情况是当前事务居然成功提交了...

return repository.save(freshMyEntity);

EDIT 2:关于repository.save()的返回结果
repository.save()返回的是完全相同的对象——相同的引用、相同的version值。我原本以为它应该返回一个更新后的新对象。

EDIT 3:调试后的发现
经过长时间调试,我找到了问题的根源:当UpdateCoordinatorStandart.doStaticUpdate执行UPDATE操作时,代码中final MutationExecutor mutationExecutor = executor( session, staticUpdateGroup, false );这一行选择了MutationExecutorSingleBatched作为执行器,而这个执行器并没有实现AbstractMutationExecutor中的OperationResultChecker resultChecker接口。

在COMMIT执行UPDATE的阶段,ModelMutationHelper.checkResults( resultChecker, statementDetails, affectedRowCount, -1 );这行代码并没有被执行,因此不会抛出异常,乐观锁也就失效了。

而在旧事务模式下执行时,走的是完全不同的代码路径:实体版本检查不是在COMMIT阶段执行,而是在EntityManager的MERGE操作中进行,并且会从数据库刷新目标对象,之后还会执行update结果的version校验。

EDIT 4:问题上报状态
目前这个问题已经上报至Hibernate官方Issue平台,现在我需要找到临时的解决方案...

备注:内容来源于stack exchange,提问作者viking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:03:05