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.目前更新方案待定