IT评测·应用市场-qidao123.com技术社区

标题: 通俗易懂分布式事务之2PC、3PC、Seata AT模式、Seata TCC模式 [打印本页]

作者: 宁睿    时间: 2025-3-27 17:35
标题: 通俗易懂分布式事务之2PC、3PC、Seata AT模式、Seata TCC模式
通俗易懂分布式事务之2PC、3PC、AT、TCC

单机服务事务提交回滚操作是需要拿到Connection对象,调用提交commit方法或者rollback方法回滚的,比方下面操作
  1. Connection conn = DriverManager.getConnection(...);
  2. try{
  3.   con.setAutoCommit(false);
  4.   Statement stmt = con.createStatement();
  5.   //1 or more queries or updates
  6.   con.commit();
  7. }catch(Exception e){
  8.   con.rollback();
  9. }finally{
  10.   con.close();
  11. }
复制代码
要想提交或者回滚,必须拥有Connection对象,然而在分布式情况,jvm都是不同的,自然就拿不到其他服务的Connection对象,所以在分布式情况,我们无法保证原子性。因此分布式事务就需要另寻出路。
1. 术语

2. 2PC

2PC 即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase)
与本地事务的区别就是 会加入一个事务协调者的角色,这个事务协调者控制整体的事务提交
2.1 流程

在这里举个具体的例子
我们有两个服务:订单服务、库存服务
用户需要买东西,起首要创建订单,创建订单前需要去锁定库存,然后再去创建订单。
  1. 1. 事务协调者开启全局事务
  2. 2. 库存服务开启事务,向事务协调者注册一个分支事务
  3. 3. 库存服务锁定库存
  4. 4. 订单服务开启事务,向事务协调者注册一个分支事务
  5. 5. 订单服务创建订单
  6. 6. 事务协调者进行全局提交事务
  7. 7. 库存服务提交事务
  8. 8. 订单服务提交事务
  9. 9. 全局事务完成
复制代码
在任何一个流程中非常,事务协调者都会发起全局回滚事务,这种方式,在全局事务完成前,Connection对象都不会释放,因为你释放了你就无法控制了,缺点很明显,如果订单服务需要处置惩罚很久,库存服务Connection对象都不会释放,一直占用着,这种是强原子性的很浪费资源
2.2 实现2PC

XA协议,是X/Open组织提出的跨异构技术实现2PC的接口尺度。
使用XA协议起首条件就是,需要关系型数据库支持,目前主流数据库:
2.2.1 MySQL实现流程:

第一步开启XA事务
库存DB:
  1. XA START 'xid'
  2. UPDATE  product SET num = num - 1 where id = 100
  3. XA END 'xid'
复制代码
订单DB:
  1. XA START 'xid'
  2. INSERT INTO order values(xxx)
  3. XA END 'xid'
复制代码
第二步,准备就绪,等待事务协调者同意我提交
库存DB:
  1. XA PREPARE 'xid'
复制代码
订单DB:
  1. XA PREPARE 'xid'
复制代码
全部提交
库存DB
  1. XA COMMIT 'xid'
复制代码
订单DB:
  1. XA COMMIT 'xid'
复制代码
2.2.3 seata支持XA

XA协议JDK接口界说:javax.sql.XADataSource
seata框架支持XA协议,seataXA模式文档:https://seata.apache.org/zh-cn/docs/v1.6/dev/mode/xa-mode/
seata官方XA模式demo:
https://github.com/apache/incubator-seata-samples/tree/master/xa-sample/springboot-feign-seata-xa
2.3 2PC缺陷

2. 3PC

三阶段提交协议(3PC)重要是为相识决两阶段提交协议的阻塞问题,2pc存在的问题是当协作者崩溃时,参与者一直阻塞。
与两阶段提交不同的是
2.1 流程:

2.2 缺点

还是要等到全局事务完毕资源才释放,占用资源大
3. Seata AT模式

Seata AT模式文档:https://seata.apache.org/zh-cn/docs/v1.6/dev/mode/at-mode
Seata AT模式的核心是对业务无侵入,是一种改进后的2PC
重要的实现是,在每个服务的数据库中新建一张undo_log表,布局如下:


content: 更改后的内容,
rollback_info: 回滚的内容
每个分支事务执行SQL都会剖析SQL,保存content,rollback_info,插入到undo_log表中。如果全局事务通知需要回滚,去通过对比content和剖析rollback_info,执行sql达到回滚的效果,如果全局事务通知全局事务成功,异步删除undo_log的记录。
这种方式不需要等待全局事务的提交才提交,能解决2PC、3PC资源占用的问题,实际就是非常就去补偿的思想
3.1 流程

3.2 缺点

seata AT模式,事务是软状态需要考虑数据终极同等性,性能相对来说不是那么高,得去加锁,得动态去剖析SQL插入数据库增加了和数据库的交互
4. Seata TCC模式

Seata  TCC模式文档:https://seata.apache.org/zh-cn/docs/v1.6/dev/mode/tcc-mode
TCC 是分布式事务中的二阶段提交协议,它的全称为 Try-Confirm-Cancel,即资源预留(Try)、确认操作(Confirm)、取消操作(Cancel),TCC模式对代码的入侵很大,但它的性能很好,还可以便捷的解决、空回滚、幂等、悬挂问题。
空回滚:没有执行try却执行了cancel。参与者分支注册完成之后会执行参与者一阶段try RPC 方法发送rpc时候网络耽误抖动,事务协调者全局回滚,参与者没有执行try却进入cancel
幂等:多次进入try。执行完二阶段之后,由于网络抖动或者宕机问题,会造成事务协调者收不到参与者执行confirm的返回结果,事务协调者会重复发起调用,直到二阶段执行结果成功
悬挂:执行了cancel又进入try。进入try 方法时,出现网路拥堵,由于 seata 全局事务有超时限制,执行 try 方法超时后,进行全局回滚,回滚完成后如果此时 RPC 哀求才到达参与者 ,执行 try 方法进行资源预留,从而造成悬挂。
Seata社区这个博客写的挺好 https://seata.apache.org/zh-cn/blog/seata-tcc/ 表明了seata是怎么样处置惩罚解决、空回滚、幂等、悬挂问题。
4.1 流程

假设一个转账需求,A给B转100,一般做法是判断够不够钱,如果够钱A-100,B+100
在TCC模式下把这个需求拆分为 Try-Confirm-Cancel
4.2 缺点

TCC模式有代码侵入,需要把一个业务拆分为三个方法,事务具有软状态,确认和取消操作都可能出现问题,需要考虑如那边理失败情况以保证终极同等性

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4