分布式事务
一 、XA协议
- XA协议有X/open组织提出的一个分布式事务处理规范
- 同服务多数据源操作不同数据库情况下可使用。
XA协议包含一个DTP模型
AP :应用程序,事务发起结束的地方
RM :资源管理器,管理每个数据库的连接数据源
TM :事务管理器,事务的全局管理,生命周期,资源分配
XA规范了TM与RM之间的通信接口,形成双向通信桥梁,在多个DB资源下保证ACID

二 、 二阶提交(2pc)
- JTA是基于XA规范实现的一套Java事务编程接口,是一种二阶提交事务。
第一阶段,AP向TM发起事务,TM向RM发起预处理请求,RM打开本地DB事务,执行事务不立即提交事务,向TM返回就绪或未就绪状态,各个参与节点都返回状态了,就进入第二阶段
第二阶段,如果RM返回的都是就绪状态,TM就向RM发送提交通知,RM完成本地DB事务提交,返回结果给TM。
如果RM返回有一个未就绪状态,此时TM就会向所有RM发送事务回滚,则各个RM就会回滚本地DB事务,释放资源,返回结果给TM。

- 缺点 :
1 、各个RM节点存在阻塞,只有当所有节点准备完成,TM才会进行全局提交通知,这个过程如果过长,则影响整个节点性能,一旦RM挂了,就会一直阻塞等待,可通过设置事务超时时间来解决。
2 、 最后通知提交全局事务时,由于网络故障,部分节点未收到通知,没有提交事务,导致数据不一致。
三 、 三阶提交(3pc)
第一阶段:询问各个资源节点是否可以执行事务
第二阶段:所有节点反馈可以执行事务,才开始执行事务
第三节点:执行提交或回滚操作
在TM与RM都引入超时机制,如果第三阶资源节点一直接受不到RM的提交或回滚请求,就会在超时后,继续提交事务。
- 缺点 :
最后提交全局事务时,网络故障,无法通知一些节点,特别是回滚通知,导致事务超时而默认提交,数据不一致。
四 、事务补偿机制(TCC)
- 采用最终一致性方式实现一种柔性分布式事务,基于服务层的一种二阶事务提交
- 跨服务分布式事务情况下使用,常用中间件TCC-transaction
分为三个阶段: Try 、Confirm 、Cancel
try阶段:尝试执行业务,执行各个服务的try方法,主要包括预留操作。
confirm阶段:确认try中的各个方法执行成功,通过TM调用各个服务的confirm方法,这个阶段为提交阶段。
cancel阶段:当try阶段发现其中一个try方法失败,则会触发TM调用各个服务cancel方法,对全局事务进行回滚。
当confirm与cancel阶段出现异常,TCC会不停的重新调用失败的confirm或cancel方法,直到成功为止。

- 缺点 :
对业务的侵入性非常大,编写大量业务性代码,try、confirm、cancel方法,还需要为每个方法考虑幂等性
五 、 seata(fescar)
- 阿里开源的一套分布式事务解决方案
基础建模跟DTP模型类似,将TM分的更细,抽出一个事务协调器(TC),主要维护全局事务的运行状态负责协调全局事务的提交或回滚。
TM负责开启全局事务,并最终发起全局提交或回滚决议。
设计初衷是解决分布式带来的性能问题以及侵入性问题。
- 整个事务流程:
1 、 TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID;
2 、 XID在微服务调用链路的上下文中传播;
3 、 RM向TC注册分支事务,将其纳入XID对应全局事务的管辖
4 、 TM向TC发起针对XID的全局提交或回滚决议
5 、 TC调度XID下管辖的全部分支事务完成提交或回滚清求。

- seata与其他分布式最大的区别在于:
在第一阶段就已经将各个事务操作commit,认为正常的业务下提交事务大概率是成功的,节约了两个阶段持有锁的时间,提高整体效率。
- 如何回滚?
seata将RM提升到服务层,通过JDBC数据源代理解析sql,把业务数据再更新前后的数据镜像组织成回滚日志。
如果TC决议要全局回滚,会通知RM进行回滚操作,通过XID找到对应的回滚日志记录,通过回滚记录生成反向更新sql,进行更新回滚操作。
- seata设计通过TC的全局写排它锁,来保证事务间的写隔离,读写隔离级别默认为未提交读的隔离级别。
内容源于极客时间app -《java性能调优实战》,侵删。