分布式事务解决方案及其原理分析

云原生背景下,Apache-Dubbo-服务自省架构值得学习

分布式事务相关概念

事务

在一个操作单元中,所有的操作要保持一致的行为,要么全部成功,要么全部失败。

分布式事务
事务的协调者,参与者,支持事务的服务器,运行事务的操作分布在不用的机器上,操作着不同的数据库,却想要实现所有的操作保持一直的行为。

产生原因:

  1. 业务扩展,服务 / 表的拆分
  2. SOA和微服务架构开发
  3. 模块之间调用,可能存在网络异常等问题,造成调用失败

常见场景

在常见的电商领域,下单操作时,需要锁定库存,锁定优惠卷等操作。假如下单模块,商品模块,优惠卷模块都是不同的服务,这时候下单操作势必会涉及到模块之间的调用,数据一致性问题就需要引入分布式事务来解决。
在这里插入图片描述

分布式事务相关术语

  • X/Open DTP 事务模型
    是X/Open 这个组织定义的一套分布式事务的标准,也就是定义了规范和 API 接口,由各个厂商进行具体的实现。DTP 是分布式事务处理(Distributed Transaction Processing)的简称。
  • XA 接口
    XA是由X/Open组织提出的分布式事务规范,XA规范主要定义了(全局)事务管理器™和(局 部)资源管理器(RM)之间的接口,主流的数据库产品都实现了XA接口,是一个双向的系统接口,在事务管理器以及多个资源管理器之间作为通信桥梁。
  • JTA
    Java Transaction API,java根据XA规范提供的事务处理标准。
  • AP
    Application,应用程序层,业务层,微服务模块等。
  • RM
    Resource Manager,资源管理器。一般是数据库,也可以是其他资源管理器,比如消息队列,文件系统。
  • TM
    Transaction Manager ,事务管理器、事务协调者,负责接收来自用户程序(AP)发起的 XA 事务指令,并调度和协调参与事务的所有 RM(数据库),确保事务正确完成。

关于XA,TM,RM之间的关系

在这里插入图片描述

分布式事务常见解决方案

XA模式

一般习惯称之为二阶段提交(2PC),是 XA 用于在全局事务中协调多个资源的机制,MySql5.5以上开始支持

核心思想

  1. 准备阶段:
    事务管理器(TM)给每个参与者(RM)发送 Prepared 消息,每个参与者开始执行自己的本地事务性消息,并保存 redo/undo 日志,此时事务还没有提交。
  2. 提交/回滚阶段:
    如果事务管理器收到参与者的执行失败或者超时等异常操作时,则给每个参与者下发回滚(callback)指令,否则下发提交(commit)指令。参与者收到事务管理器的提交/回滚指令后,根据redo/undo日志执行相应操作,并释放相应资源(锁,空间等)。

在这里插入图片描述

总结

  1. XA协议简单,数据库支持XA协议,开发使用成本比较低
  2. 对业务侵⼊很小,最⼤的优势就是对使⽤⽅透明
  3. 用户可以像使⽤本地事务⼀样使⽤基于 XA 协议的分布式事务,能够严格保障事务 ACID 特性
  4. 事务执⾏过程中需要将所需资源全部锁定,也就是俗称的刚性事务(遵循ACID)
  5. 性能不理想,占用锁资源比较多,高并发常见下无法满足

TCC

简称TCC柔性事务(遵循Base理论),和 2PC 思想类似

核心思想

将事务提交分为:

  • Try
    完成所有业务检查( 一致性 ) ,预留必须业务资源( 准隔离性 )
  • Confirm
    对业务系统做确认提交,默认 Confirm阶段不会出错的。即只要Try成功,Confirm一定成功
  • Cancel
    业务执行错误,需要回滚状态下执行业务取消,释放业务资源,进行补偿。

在这里插入图片描述

优点

  1. 把事务分为try,confirm,concel阶段,每个阶段由业务代码进行控制,事务的锁力度可自由控制,资源阻塞概率低

缺点

  1. 每个阶段都是由业务代码进行控制,场景变化后复用性差,维护成本高
  2. 需要保证幂等性操作,避免多次异常操作造成数据异常

AT模式(参考自分布式事务框架Seata

避免了业务代码侵入,用户只需要关系自己的业务SQL

核心思想

  1. 执行用户SQL:
    Seata会拦截“业务SQL”,找到“业务SQL”要更新的数据,在更新数据之前生成“before image”镜像,然后执行“业务SQL”更新数据,更新数据后,生成“after image”,最后生成行锁。以上所有操作都在同一个事务中执行,确保一阶段原子性。

  2. Seata框架自动生成提交或者回滚:
    二阶段提交:由于一阶段已经完成了对数据的更新操作,这时候只需要释放对应的锁资源,删除快照数据,完成数据清理即可。
    二阶段回滚:根据一阶段生成的“before image”镜像完成数据回滚操作,不过在回滚之前需要效验“after image”和当前数据是否吻合,不吻合说明出现了脏写,这时候需要转人工或者提交工单特殊处理,吻合的话则直接还原业务数据。

消息队列

消息队列提供类似Open XA的分布式事务功能,通过消息队列事务消息能达到分布式事务的最终一致

核心思想

概念

  • 半事务消息:

    暂不能投递的消息,消息已经被生产者发送到了服务端Broker,然而Broker没有收到生产者对于本消息的二次确认,此时消息被标记为“暂不能投递状态”,处于该状态下的消息被称为“半事务消息”。

  • 消息回查:

    由于网络因素,生产者异常,导致某次事务的二次确认消息丢失,Broker通过扫描发现某条消息长期处于“半事务消息”状态,需要主动向消息生产者询问该消息的最终状态(Commit/Rollback),该询问过程被称为消息回查

在这里插入图片描述
注意

  • 目前较为主流的MQ,比如ActiveMQ、RabbitMQ、Kafka、RocketMQ等,只有RocketMQ支持事务消息。如果其他队列需要事务消息,可以开发个消息服务,自行实现半消息和回查功能
  • 事务消息可以实现应用之间的解耦,不会因为其中一个非核心模块的异常造成整个链路回滚,最大程度上保证了核心系统的可用性。
  • 只能保证数据最终一致性,实时性得不到保障,极端情况下还需要人工介入。另外单独的服务接入,系统可维护性降低。

补充:

分布式事务框架Seata原理

seata

重新定义相关术语

  • TC
    Transaction Coordinator 事务协调器,管理全局的分支事务状态,用于全局分支事务的提交和回滚
  • TM
    Transaction Manager 事务管理器,用于开启事务,决策全局事务提交还是回滚
  • RM
    Resource Manager 资源管理器,分支事务的资源管理,向TC注册分支事务,上报分支事务状态,接受TC命令来提交/回滚分支事务

架构:TC 为单独部署的 Server 服务端,TM 和 RM 为嵌入到应用中的 Client 客户端

在这里插入图片描述
执行流程

  1. TM向TC申请开启一个全局事务,TC返回给TM一个XID,用于在微服务调用链路中传播
  2. A服务的RM向TC注册分支事务,接着执行分支事务并提交,并给TC汇报执行结果
  3. A服务开始远程调用B服务,并传递XID
  4. B服务的RM向TC注册分支事务,执行分支事务,给TC汇报执行结果,接着调用下一条链路,直至单次链路调用完毕
  5. 全局事务链路调用完毕,TM根据TC上汇总的每个分支链路调用结果来决定全局事务提交还是回滚,并将结果返回给TC
  6. TC调用XID管辖下的所有分支事务完成提交/回滚请求

Seata 实现分布式事务,关键角色UNDO_LOG(回滚日志记录表)

在每个应用需要分布式事务的业务库中创建这张表,这个表的核心作用是将业务数据在更新前后的数据镜像组织成回滚日志,保存在UNDO_LOG表中,以便业务异常能随时回滚

Seata能够在第一阶段直接提交事务,是因为Seata框架为每一个RM维护了一张UNDO_LOG表(这张表需要客户端自行创建),其中保存了每一次本地事务的回滚数据。因此,二阶段的回滚并不依赖于本地数据库事务的回滚,而是RM直接读取这张UNDO_LOG表,并将数据库中的数据更新为UNDO_LOG中存储的历史数据。

如果第二阶段是提交命令,那么RM事实上并不会对数据进行提交(因为一阶段已经提交了),而实发起一个异步请求删除UNDO_LOG中关于本事务的记录。

bilibili账号:段某人
文章持续更新,可以微信扫码关注第一时间阅读
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值