Spring事务REQUIRES_NEW,REQUIRED【开启多线程,事务嵌套】

1.运用场景:

        外部上传黑名单文件,对文件读取,对传入的数据在缓存中进行更新或者新增

2.1 REQUIRES_NEW,REQUIRED(参照学习链接

        REQUIRED表示如果当前没有事务,就创建一个事务,如果已经存在一个事务,就加入该事务,是Spring默认的事务传播类型

        REQUIRES_NEW表示如果当前存在事务,则把当前事务挂起,重新创建新的事务并执行,知道新的事务提交或回滚,才会恢复执行原来的事务。这种事务传播类型新创建的事务和被挂起的事务没有任何关系,他们是两个相互独立的事务,外部事务失败后回滚,不会回滚内部事务的执行结果,内部事务执行失败抛出异常,被外部事务捕获时,外部事务可以不处理内部事务的回滚操作

2.2.原代码

      service业务层

serviceA上面的注解是:

@Transactional(propagation= Propagation.REQUIRED)

        使用多线程代码:

        

public void sss()  {
        //创建实体类
        CheckInfo checkInfo = new CheckInfo();
        //实体类必传字段 
        checkInfo.setAppName("aikang");
        checkInfo.setOrgCode("kkkkkk");
        checkInfo.setStatDate(new Date());
        checkInfo.setTokenId("111111111111111111111111");
        checkInfo.setCheckStatus(5);
        //调用保存实体类方法
        checkInfoMapper.saveCheckInfo(checkInfo);
        LOGGER.info("========= ssss =fu== start========");
        //创建存放线程的集合,之后遍历集合查看线程完成情况
        ArrayList<Future<Boolean>> futures = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Integer nn = i;
            //线程池提交需要操作的数据文件(此处是伪代码)
            Future<Boolean> submit = ThreadPoolUtils.threadPool
                        .submit(() -> checkServiceImpl.kkk(nn));
            //执行完成加入集合中
            futures.add(submit);
        }
        //多集合进行迭代查看
        Iterator<Future<Boolean>> iterator = futures.iterator();
        while (true) {
            if (!iterator.hasNext()) {
                break;
            }
            Future<Boolean> next = iterator.next();
            try {
                if(next.get()){
                    iterator.remove();
                    LOGGER.error("ee: {}",next.get());
                }
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new BusException("1111");
            } catch (ExecutionException e) {
                throw new BusException("1111");
            }


        }
        LOGGER.info("========= ssss =fu== end========");

    }
serviceB上面的注解是:
@Transactional(propagation= Propagation.REQUIRED)
public boolean kkk(int num){
        LOGGER.info("========= kkkk =zi== start========");
        //新建对象
        CheckInfo nn = new CheckInfo();
        nn.setAppName("qqq");
        nn.setStatDate(new Date());
        nn.setOrgCode("www");
        nn.setTokenId("111111111111111111111111k"+num);
        nn.setCheckStatus(5);
        checkInfoMapper.saveCheckInfo(nn);
        //如果传值进来的数值等于9,则进入判断,由于999999查询不到数据,会报空,测试回滚会到什
        //么程度
        if (num == 9){
            CheckInfo rr = new CheckInfo();
            rr.setAppName("uuuu");
            rr.setStatDate(new Date());
            rr.setOrgCode("oooo");
            rr.setTokenId("2222222222222222");
            rr.setCheckStatus(7);
            checkInfoMapper.saveCheckInfo(nn);
            CheckInfo checkInfo = checkInfoMapper.selectById(999999);
            if (checkInfo.getCheckUser().equals("kkk")){
                System.out.println("子事务");
            }
        }
        LOGGER.info("========= kkkk =zi== end========");
        return true;
    }

1.ServiceA、ServiceB都使用,只回滚ServiceA的以及ServiceB中有异常的。

@Transactional(propagation= Propagation.REQUIRES)

2.ServiceA使用REQUIRES、ServiceB使用REQUIRES_NEW,同样也是回滚ServiceA的以及ServiceB中有异常的(附图1),需要注意的是:这里回滚A是由于在A中使用了try  catch才回滚,如果没有使用try  chtch是不会回滚A的(附图2)。

     附图1

 
 

 附图2                      

3.目前更新方案待定

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值