ActivitiOptimisticLockingException:was updated by another transaction concurrently

场景:

本地接口测试正常,线上环境说调用接口一直报ActivitiOptimisticLockingException:was updated by another transaction concurrently

描述:

需求很简单就是同时更新两个表中的一个字段。

act_biz_suspension ,act_hi_biz_suspension 中通过id去更新suspendType字段,两个表中id是一样的

@Override
public Void execute(CommandContext commandContext) {
    if(businessSuspension == null) {
        throw new ActivitiIllegalArgumentException("businessSuspension is null");
    }
   // 更新act_biz_suspendsion
    commandContext.getBusinessSuspensionEntityManager().updateBusinessSuspension(businessSuspension);

    //同时更新act_hi_biz_suspendsion历史表 2016-01-06
    HistoricBusinessSuspensionEntity historicBusinessSuspensionEntity =
            new HistoricBusinessSuspensionEntity((BusinessSuspensionEntity)businessSuspension);

    commandContext.getHistoricBusinessSuspensionEntityManager().updateHistoricBusinessSuspension(historicBusinessSuspensionEntity);
    return null;
}

分析:

报错翻译就是乐观锁异常,被另一个事务同时更新

 原因:

前端传的id在act_biz_suspension表中是不存在的,然而在act_hi_biz_suspension是存在的,这样在更新第一张表的时候就会报错回滚,然而我本地测试的时候是按照两个表同时有数据测试的因此没啥问题,忽视了一个表中存在数据一个表中不存在数据的情况。

这是因为在 MySQL 中,乐观锁的实现是通过版本号(我们数据库是有版本号的)或时间戳等机制来实现的,如果一个表的更新操作失败了,另一个表的版本号或时间戳就会不匹配,导致另一个表的更新操作也失败。

结论:

1.因此在使用 MySQL 数据库时,在一个事务中同时更新两个表时,需要确保两个表的更新操作都能成功。如果其中一个表的更新操作失败了,整个事务就会回滚,包括另一个表的更新操作也会回滚,并且会抛出乐观锁异常。

2.本质上还是我的代码写的有问题,在同时更新多个表时,没有对入参数进行校验

猜你喜欢

转载自blog.csdn.net/qq_38423256/article/details/130704818
今日推荐