Springboot中事务的使用

189 阅读2分钟
  1. 启动类加上@EnableTransactionManagement注解,开启事务支持(其实默认是开启的)

  2. 在使用事务的public(只有public支持事务)[方法](或者类-相当于该类的所有public方法都使用)加上@Transactional注解。

    在实际使用中一般是在service中使用@Transactional,那么对于controller->service[流程]中:

    如果controller未开启事务,service中开始了事务,service成功执行,controller在之后的运行中出现异常(错误),不会自动回滚。

    也就是说,只有在开启事务的方法中出现异常(默认只有非检测性异常才生效-RuntimeException )(错误-Error)才会自动回滚。

    如果想要对抛omHWQNuj出的任何异常都进行自动回滚(而不是只针对RuntimeException),只需要在使用@Transactional(rollbackFor = Exception.class)即可。

    开启事务的方法中事务回滚的情况:

    ①未发现的异常,[程序]运行过程中自动抛出RuntimeException或者其子类,程序终止,自动回滚。

    ②使用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();进行手动回滚。

    ③注意:如果在try-catch语句中对可能出现的异常(RuntimeException)进行了处理,没有再手动throw异常,spring认为该方法成功执行,不会进行回滚,此时需要调用②中方法进行手动回滚,如下图:

    另外,如果try-catch语句在finally中进行了return操作,那么catch中手动抛出的异常也会被覆盖,同样不会自动回滚。 `

     //不会自动回滚
     try{
         throw new RuntimeException();
     }catch(RuntimeException e){
         e.printStackTrace();
     }finally{
    
     }
    

    //会自动回滚
    try{
        throw new RuntimeException();
    }catch(Ruhttp://ntimeException e){
        e.printStackTrace();
        throw new RuntimeException();
    }finally{

    }

如果只要回滚【添加表】的操作而不回滚【记录接口调用信息】操作,可以设置[事务回滚]点并手工回滚异常(针对try-catch并实现部分回滚)

@Transactional(rollbackFor = Exception.class)
.........
//设置事务回滚点
Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
//添加表
List<FundInfoBO> fundInfoBOList = this.insertAccrueInteRel(fundInfoBOS);
// 构造请求参数
InterestBaseDTO interestBaseDTO = this.assemblyInterestReqData(fundInfoBOList);
BaseRequestDTO<Object> interestReqBaseDTO = RequestBuild.createBaseRequest(interestBaseDTO);
try {
    //调用接口
    BaseResponseDTO<FinanceSendResp> financeResponseDTO = financeJsxbFeign.syncInterestRateInfo(interestReqBaseDTO);
    FinanceSendResp financeSendResp = financeResponseDTO.getPayload();
    //处理响应信息
    this.dealFinanceRespInfo(financeSendResp);
} catch (MsdpBusinessException e) {
    //手工回滚异常
    TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
    return ResponseBuild.buildFailResponse(e.getCode(), e.getMessage());
} finally {
    // 获取响应信息
    if (Objects.nonNull(interestReqBaseDTO)) {
    // 记录接口调用信息
    interfaceCallService.insertRecord(DgmsConst.YING_JI_LI_XI, DgmsDiConst.SYS_DGMS_FUND,
    interestReqBaseDTO, financeResponseDTO1);
        }
    }

`