【SEATA源码分析】记一次 pr

一 . 导读

为什么为想起来贡献 pr 呢?在写这个 pr 之前,研究了一个多月 seata 源码,看的多了手就痒了,恰好又看到了社区的 issues ,于是就动手了。

二. pr 相关

pr 内容:参与方回滚,地址。由参与方通知TC回滚,可以提前结束全局事务并释放锁,提高seata事务的吞吐量;至于发起方可以接收参与方抛出的约定异常,不再通知TC,直接结束。

这里简单介绍一下现如今的做法,只有发起方才能发起回滚的流程:

1.被 @GlobalTransactional 注解的方法都会进入模板类进行处理。如果参与方抛出了异常,发起方这里会调用 completeTransactionAfterrThrowing(txInfo, tx, ex) 进行异常相关的处理。
在这里插入图片描述
2.这里判断如果是需要回滚的异常,则通过 rpc 通知 tc 进行全局事务的回滚。并且向上层抛指定 code 为 RollbackFailure 的异常。

在这里插入图片描述
3.这里判断是何种行为的异常,然后执行对应的处理方法。
在这里插入图片描述
4.如果事务的角色是参与方,则直接返回。参与方没有向 tc 上报发起全局回滚的职责。这里的方法在上图标记为 3 的地方调用。
在这里插入图片描述

三. 实现 pr

第一个版本设计的很简单,去掉发起方才能回滚的限制,然后增加一种 code :ParticipantReportRollback ,如果接收到这种异常的 code,interceptor 处理完抛异常给上层。

经过社区大佬提醒,意识到这么做有几个问题:

1.code 只增加了一种,只考虑参与方上报的情况,没有意识到参与方上报成功和失败是两种情况。

2.异常有很多种,有的是 seata 自身流程处理产生的异常,有的是使用者的业务异常,最终 interceptor 抛给上层的,应该是阻止流程进行下去的异常。

3.rpc 框架会拦截异常。

前两个问题挺好解决的,因为只要 pr 的思路没问题,其他情形完善一下就 ok 了。

为了防止思考的不全面,我还写了一个很多个逻辑分支的测试类:
-》表示抛异常,参与方 -》参与方-》发起方,参与方-》发起方,发起方-》。每一种都分两种情况,回滚成功和回滚失败。

第三个问题就很棘手,不同的 rpc 框架对待异常的行为不一样,比如 feign,接受 500 时,会包装成 FeignException ,再抛给消费者。所以这里根据异常的类型来处理就不行了。

一般 rpc 框架可能不会把消费者异常还原成提供者抛出的异常,但是一般 Exception 中的 message 会保留下来,通过 try 是可以获取到的。FeignException 就保留了 message 放在 byte[] 数组中。

所以如果要解决这个问题,就需要解析 rpc 框架的异常,但是每种 rpc 框架的异常都不一样,这就很棘手了。

四 .总结

pr 虽然还未合并,但已收获良多。写业务代码绕不开事务,分布式项目就绕不开分布式事务,好好研究一下 seata 源码还是很有必要的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值