一、阐明
此处只是简略的记录一下,应用了 Seata
后,如何手动 回滚分布式事物和长期挂起分布式事务,Seata的整合不做具体的阐明。
二、性能实现
1、手动回滚分布式事物
举例:
- 比方咱们通过feign去调用第三方服务,feign服务呈现了降级。
- 调用第三方api,第三方api调用失败,是通过 谬误吗 来告知是胜利还是失败的。
class 手动回滚分布式事物{ public void 局部代码() { if (RootContext.inGlobalTransaction()) { try { GlobalTransactionContext.reload(RootContext.getXID()).rollback(); } catch (TransactionException e) { log.error("回滚分布式事物出现异常", e); } } } }
拜访申请:
$ curl -X GET http://localhost:50017/rollbackTx\?accountId\=1\&amount\=10\&hasException\=false
后果:
- 当账户服务的返回值 <= 5 时,事物回滚,账户服务不扣钱,订单服务不产生订单
- 当账户服务的返回值 > 5 时,账户服务扣钱,订单服务产生订单
2、长期挂起分布式事物
举例:
- 在一个大的分布式事务中,如果分布式事物的某个环节呈现了异样,通过
try{}catch(){}
后,须要记录一个日志到数据库中,此处可能须要挂起这个分布式事务,让记录日志的办法不参加到分布式事务中。
下方这个案例是模仿下单操作,下单分为 账户服务扣钱和产生订单,此处将账户服务扣钱操作排除到分布式事务外,产生订单参加分布式事务。
class 长期挂起分布式事物 { @GlobalTransactional(rollbackFor = Exception.class) public void 局部代码(){ String xid = RootContext.getXID(); System.out.println("createAccountOrder:" + xid); // 解除 xid 的绑定 RootContext.unbind(); // 1、近程扣减账户余额 // =============== 此办法不在分布式事务中================= boolean debitResult = remoteDebit(accountId, amount); // =============== 此办法不在分布式事务中================= // 从新绑定 xid RootContext.bind(xid); // 2、下订单 orderService.createOrder(accountId, amount); // 抛出异样 int i = 1 / 0; }}
拜访申请:
$ curl -X GET http://localhost:50017/bindAndUnBind\?accountId\=1\&amount\=10\&hasException\=false
后果: 账户服务扣钱,没有产生订单
三、残缺代码
https://gitee.com/huan1993/spring-cloud-parent/tree/master/seata/seata-springboot-rollback-tx
四 参考链接
http://seata.io/zh-cn/blog/seata-spring-boot-aop-aspectj.html