批处理业务,循环中保证事务的一致性,手动开启提交或回滚

 

说明:业务需求是批量调拨,这些调拨的数据的数据,如果单条成功了,提交事务,就继续执行下一条;如果失败了,也不影响下一条的执行,最后把成功和失败的结果记录上就OK;这就要保证for循环中每一条执行的事务一致性。
每一次循环中必须有一次手痛回滚或者提交的操作,是为了释放事务的资源;
代码为示例子代码,只要关注红色标注部分的代码即可;

@Autowired
private PlatformTransactionManager transactionManager;

/**
 * 批量调拨(不是整个方法事务,支持循环代码块事务)
 *
 * @param fromNode
 * @param toNode
 * @param vehicleList
 * @return
 */
@Override
public List<BatchAllotResultVo> batchAllot(String fromNode, String toNode, List<BaseVehicleListTo> vehicleList, AmpUser user) throws BizException {
    log.info("********************批量调拨开始******************************");
    log.info("出发VDC:{}", fromNode);
    log.info("目的VDC:{}", toNode);
    log.info("调拨数据总条数:{}",vehicleList.size());
    Assert.hasLength(fromNode, "出发VDC不可以为空");
    Assert.hasLength(toNode, "目的VDC不可以为空");
    Assert.notEmpty(vehicleList, "车辆不可以为空");

    VlBaseNode baseNode = feignHelper.getNodesByCode(toNode);
    //调拨时间,每次调拨所有的调拨必须是同一个调拨时间,调拨历史会根据调拨时间和调拨操作人分组查询,确定一次调拨
    LocalDateTime allotTime= LocalDateTime.now();

    List<BatchAllotResultVo> resultVos = new ArrayList<>();
    for (int i=0 ;i<vehicleList.size();i++) {
        //每一次循环开启一个事务,出现异常手动关闭,没有异常手动提交事务
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事   务,这样会比较安全些。
        TransactionStatus status = transactionManager.getTransaction(def);

        BaseVehicleListTo v=vehicleList.get(i);

        BatchAllotResultVo resultVo=new BatchAllotResultVo();
        resultVo.setVehicleCode(v.getVehicleCode());
        try {
            log.info("********执行调拨第"+(i+1)+"条:{}", JSON.toJSONString(v));

            //校验:CV没有绑定销售订单,VL没有未完成的释放,VL没有质损;

            //(1) 更新CV系统所属VDC
           boolean updateVdcRes= vehicleManager.updateVdc();
           if(updateVdcRes){
               log.info("(1):更新车辆主表所属VDC成功");
           }else {
               //手动开启事务回滚
               transactionManager.rollback(status);
               log.info("(1):更新车辆主表所属VDC失败");
               resultVo.setResult(false);
               resultVo.setDesc("失败:不存在该车辆,或者车辆的数据已经被修改,请重新调拨");
               resultVos.add(resultVo);
               continue;
           }

            //(2) 插入调拨历史
            CvAllotHistory history = CvAllotHistory.builder().vehicleCode(v.getVehicleCode()).spu(v.getSpu()).skuCode(v.getSkuCode())
                    .skuName(v.getMaterialDesc()).allotFromNode(fromNode).allotToNode(toNode).allotTime(allotTime).createUser(user.getId().toString()).createUsername(user.getName()).build();
            boolean saveHisRes= allotHistoryService.save(history);
            if(saveHisRes){
                log.info("(2):插入调拨历史成功");
            }else {
                //手动开启事务回滚
                transactionManager.rollback(status);
                log.info("(2):插入调拨历史失败,手动回滚");
                resultVo.setResult(false);
                resultVo.setDesc("失败:插入调拨历史失败,请重新调拨");
                resultVos.add(resultVo);
                continue;
            }
           //手动事务提交
            transactionManager.commit(status);
            resultVo.setResult(true);
            resultVo.setDesc("成功");
            resultVos.add(resultVo);
            log.info("********执行调拨第"+(i+1)+"条完成,执行成功。");
        } catch (RuntimeException e) {
            log.error("系统异常",e);
            transactionManager.rollback(status);
        }
    }
     long secCount= resultVos.stream().filter(BatchAllotResultVo::isResult).count();
    log.info("********************批量调拨结束,成功 "+secCount+" 条,失败 "+(vehicleList.size()-secCount)+" 条******************************");
    return resultVos;
}
 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值