之前使用过LCN分布式事务, 最近看到面试者简历中另一种方案 Seata, 通过它来在实战中解决分布式事务的问题.故 去简单了解了一下Seata是什么, 和LCN的区别在哪里, 如果是你 你怎么选择解决方案呢?
先做一个简单的总结, 慢慢后续新增更新.
下面, 简单针对俩个方案 进行简单的一个分析和对比:
相同点
a、都能解决分布式事务问题
b、都使用AOP代理事务
c、事务的提交和回滚都是由发起方决定。
不同点:
核心:事务的回滚机制不一致,LCN是全局假关闭事务,Seata是采用undo_log生成逆向sql回滚操作。
- a、LCN的事务代理是全局的,采用了假关闭模式。
Seata事务代理只是代理局部各自的事务,在原生sql的前后记录了操作的信息,存在了undo_log的日志中。 - b、LCN的事务一直都锁着记录,只是不提交而已,容易造成数据的死锁。
Seata的局部事务已经写到了库中,避免了死锁现象,但容易出现脏读的情况。 - c、LCN有控制台界面,Seata没有控制台界面
Seata:
角色:
Transaction Coordinator 事务协调器
Transaction Manager 事务管理者
Resource Manager 资源管理器
原理: TM和RM都会被seate代理数据源
- TM执行业务时,会通过aop拦截@GlobalTransactional注解,先查询ThreadLocal是否有XID,如果没有,会请求TC创建一个XID,获取到XID,保存到ThreadLocal;
- 在调用其他服务接口的时候,会把XID存放到Http请求头传给RM;
- RM从请求头上获取到XID,会保存到Threadlocal,并且向TC注册事务分支(当前微服务的);
- RM操作sql前,会记录前置镜像到undo_log表,然后执行sql,成功后再记录后置镜像到undo_log表(记录undo_log和执行业务sql是同一事务),然后提交事务;
- 5.TM调用RM返回,继续执行业务,如果异常,通知TC,然后TC通知所有事务分支进行回滚;
- 6.RM收到回滚通知,会执行后置镜像sql,将数据还原,然后删除当前XID中undo_log的镜像记录;
- 7.如果成功,通知TC,然后TC通知所有事务分支;
- 8…RM收到成功通知,删除当前XID中undo_log的镜像记录;
初衷:
解决分布式事务问题,有两个设计初衷:
- 对业务无侵入:即减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入
- 高性能:减少分布式事务解决方案所带来的性能消耗
seata中常用的有两种分布式事务实现方案,AT及TCC
- AT模式主要关注多 DB 访问的数据一致性,当然也包括多服务下的多 DB 数据访问一致性问题
- TCC 模式主要关注业务拆分,在按照业务横向扩展资源时,解决微服务间调用的一致性问题
LCN:
原理 发起方如支付服务执行业务的时候,会通过aop拦截@LcnTransaction注解,会生成一个事务组ID,然后通过netty传递给tx-manager(事务协调者)创建一个事务分组
- 执行业务代码,在调用其他服务接口(如订单服务)的时候,把事务组ID存放到Http请求头传给参与方;
- 参与方在Http请求头上收到分组id的时候,执行完业务不会提交事务,而是监听tx-manager(加入当前事务组);
- 发起方代码执行完成之后 通知给tx-manager是提交还是回滚,然后tx-manager通知给参与方做事务处理
在了解的过程中, 发现几个有图示的网址:
seata (图解_秒懂_史上最全)
阿里开源的分布式事务框架 Seata
- 希望我们都能 优秀 哇塞 发自己的光.