缺点:
1.这种方式局限性很大 但是也支持某些场景
2.原子性不能得到完全一致性的保证 但是一般能正常回滚
3 需要try catch 每次需要手动提交
4.feign调用也需要重复操作
优点:
1.可以解决异步中的回滚事物 (但是不能回滚主线程中的事物)
2.分布式事物对异步中的增删改没有效果 利用本地事物进行异常捕获来提交异常 利用Redis来保证事物是否进行回滚
1.A
@Autowired
private TransactionDefinition transactionDefinition;
@Autowired
private OrdReportBusinessService orderReportBusinessService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private FoodOrderInfoApi foodOrderInfoApi;
@GetMapping("/test")
public Result test() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
CompletableFuture.runAsync(() ->{
// 每一个线程都来共享之前的请求数据
RequestContextHolder.setRequestAttributes(requestAttributes);
TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
try{
//本地保存
boolean save1 = orderReportBusinessService.save(new OrdReportBusinessEntity().setOrderId(111L));
// int i = 1/0;
if(save1){
//feign调用保存
OrdOrderInfoEntity save2 = foodOrderInfoApi.saves(new OrdOrderInfoEntity().setOrderNo("2324594295"));
if(redisUtil.get("rollback").equals(1)){
throw new Exception("异常回滚");
}
if(Objects.equals(null,save2.getOrderNo())){
throw new Exception("添加失败回滚");
}
}
platformTransactionManager.commit(transactionStatus);
}catch (Exception e){
e.printStackTrace();
platformTransactionManager.rollback(transactionStatus);
}
},orderChangeThreadPoolExecutor);
return Result.OK();
}
2.B
@Autowired
private PlatformTransactionManager platformTransactionManager;
@Autowired
private RedisUtil redisUtil;
@Autowired
private TransactionDefinition transactionDefinition;
@PostMapping("/saves")
OrdOrderInfoEntity saves(@RequestBody OrdOrderInfoEntity entity) throws Exception {
TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
try {
OrdOrderInfoEntity ordOrderInfoEntity = foodMerchantOrderInfoService.saveEntity(entity);
//int i = 1/0;
redisUtil.set("rollback",0);
platformTransactionManager.commit(transactionStatus);
return ordOrderInfoEntity;
} catch (Exception e) {
redisUtil.set("rollback",1);
platformTransactionManager.rollback(transactionStatus);
throw new Exception("异常");
}
}
对于不能回滚主线程事物 可以采用
1.主线程数据保存失败则不走异步
2.主线程数据保存成功,异步中的事物出现了异常的话则根据主线程中保存成功的ID在异步中删除主线程中的数据并且回滚异步中的事物