@GlobalTransactional // seata全局事务开启
public void updateAfterSetSeatSell(DailyTrainTicket dailyTrainTicket , List<DailyTrainSeat> chooseSeat, List<ConfirmOrderTicketReq> tickets, ConfirmOrder confirmOrder){
LOG.info("AfterConfirmOrderService的seata全局事务id : {}", RootContext.getXID());
// OpenFeign远程调用
ResponseResult save = memberFeign.save(memberTicketReq);
}
}
全局事务处理
@ExceptionHandler(value = Exception.class)
public ResponseResult Error(Exception e) throws Exception{
LOG.info("seata全局事务id :{}", RootContext.getXID());
LOG.error("系统错误:{}",e.getMessage());
e.printStackTrace();
return ResponseResult.error(BusinessExceptionEnum.SYSTEM_ERROR);
}
远程调用接口
@Override
public void saveTicket(MemberTicketReq memberTicketReq) {
LOG.info("TicketServiceImpl的seata全局事务id : {}", RootContext.getXID());
DateTime now = DateTime.now();
Ticket ticket = BeanCopyUtil.copyBean(memberTicketReq, Ticket.class);
ticket.setId(SnowFlakeUtil.getSnowflakeNextId());
ticket.setCreateTime(now);
ticket.setUpdateTime(now);
ticketMapper.insert(ticket);
int i = 1/0;
}
当走到 i = 1/0的时候,会抛出 by Zero异常给全局异常处理,全局异常处理捕获异常后,将结果封装成为一个返回值给调用方,全局事务那边的接口就不会接收到异常信息,从而导致就算出现了异常,事务也不会正常执行
解决方法
@ExceptionHandler(value = Exception.class)
public ResponseResult Error(Exception e) throws Exception{
LOG.info("seata全局事务id :{}", RootContext.getXID());
//判断是否是全局事务中出现的异常,(因为Business层会调用Member的保存车票的代码,如果保存车票代码出现异常,会首先被这个拦截器捕获,然后封装成 ResponseResult.error,则不会被Business层捕获异常,就导致了事务失效问题)
if(StrUtil.isNotBlank(RootContext.getXID())){
throw e;
}
LOG.error("系统错误:{}",e.getMessage());
e.printStackTrace();
return ResponseResult.error(BusinessExceptionEnum.SYSTEM_ERROR);
}