spring 事务的传播行为, 没用好可能导致重复提交

2022-06-18  本文已影响0人  饱饱抓住了灵感
类型 解释 总结
REQUIRED 支持当前事务,如果不存在 就新建一个 有且只有一个, 加入别人, 或自己创建, 事务间数据共享
SUPPORTS 支持当前事务,如果不存在,就不使用事务 随缘的, 有没有都行, 事务间数据共享
NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务 打死不以事务执行, 事务间数据不共享
REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务 一定要自立门户, 建一个新事务, 事务间数据不共享
NESTED 如果当前事务存在,则嵌套事务执行 没事务会创建新建一个事务, 有事务就创建一个自事务; 父事务提交之后我再提交; 父事务失败会导致我失败; 我失败也会导致父事务失败, 进而导致其他兄弟事务失败; 我的失败可以被捕获, 被捕之后父事务和其他兄弟事务不受影响; 事务间数据共享
MANDATORY 支持当前事务,如果不存在,抛出异常 一定要有, 不然我就闹, 事务间数据共享
NEVER 以非事务方式运行,如果有事务存在,抛出异常 一定不能有, 不然我就闹, 事务间数据不共享

如下代码, 请思考: 结果会有几条"饱饱"的数据?

@Transactional(propagation = Propagation.REQUIRED)
method insert(){
    insert("饱饱");
    insertOrUpdate("饱饱");
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
method insertOrUpdate(String name){
    if(notExist(name)){
        insert(name);
    }else{
        update(name, "回家吃西瓜啦");
    }
}

思考之后, 往下滚动查看结果~
















最终结果是: 插入了2条"饱饱"的数据
解释:

  1. insert()方法是REQUIRED, insertOrUpdate()方法是REQUIRES_NEW, 2个事务间数据不共享
  2. 因为insert()方法内包含了insertOrUpdate()方法, 所以数据未提交就调用了insertOrUpdate()方法, 又因为这2个事务间数据不共享, 于是insertOrUpdate()方法无法查到"饱饱"的数据, 它的先查询再提交不能准确生效
  3. 最终, 会插入2条"饱饱"的数据, 出现重复提交的情况

总结: NOT_SUPPORTEDREQUIRES_NEW可能导致重复提交

上一篇 下一篇

猜你喜欢

热点阅读