实践丨分布式事务解决方案汇总:2PC、消息中间件、TCC、状态机+重试+幂等

本文从实践角度总结了分布式事务的七种解决方案,包括2PC、消息中间件、TCC、状态机+重试+幂等等。2PC存在性能和一致性问题,常被最终一致性、TCC等方案替代。最终一致性通过消息中间件实现,但可能存在消息丢失和重复消费问题,需要额外处理。TCC通过Try、Confirm、Cancel三阶段确保事务一致性,适合服务间的事务处理。事务状态表+调用方重试+接收方幂等方案,通过事务状态和幂等性保证一致性,对账方法则基于数据的完整生命周期和关联关系确保一致性。
摘要由CSDN通过智能技术生成

本文节选自《软件架构设计:大型网站技术架构与业务架构融合之道》一书,余春龙著,由电子工业出版社博文视点出版,已获得授权。架构是一种综合能力,而不是某一方面的技能。也正因为如此,本书提供的是一个全面的解决方案、方法论、成体系的设计思维。从基础技术谈起,之后到高层技术,再到业务、管理,提供一个架构能力的全局视图,从而诠释一个架构师的完整能力模型。


本文从实践角度总结了解决分布式事务问题,比较可靠的七种方法:两种最终一致性的方案,两种妥协办法,两种基于状态 + 重试 + 幂等的方法(TCC,状态机+重试+幂等),还有一种对账方法。


在实现层面,妥协和对账的办法最容易,最终一致性次之,TCC最复杂。


<以下为正文>




数据一致性问题非常多样,下面举一些常见例子。比如在更新数据的时候,先更新了数据库,后更新了缓存,一旦缓存更新失败,此时数据库和缓存数据会不一致。反过来,如果先更新缓存,再更新数据库,一旦缓存更新成功,数据库更新失败,数据还是不一致;


比如数据库中的参照完整性,从表引用了主表的主键,对从表来说,也就是外键。当主表的记录删除后,从表是字段置空,还是级联删除。同样,当要创建从表记录时,主表记录是否要先创建,还是可以直接创建从表的记录;


比如数据库中的原子性:同时修改两条记录,一条记录修改成功了,一条记录没有修改成功,数据就会不一致,此时必须回滚,否则会出现脏数据。


比如数据库的Master-Slave异步复制,Master宕机切换到Slave,导致部分数据丢失,数据会不一致。


发送方发送了消息1、2、3、4、5,因为消息中间件的不稳定,导致丢了消息4,接收方只收到了消息1、2、3、5,发送方和接收方数据会不一致。


从以上案例可以看出,数据一致性问题几乎无处不在。本书把一致性问题分为了两大类:事务一致性和多副本一致性。这两类一致性问题基本涵盖了实践中所遇到的绝大部分场景,本章和下一章将分别针对这两类一致性问题进行详细探讨。


随处可见的分布式事务问题


在“集中式”的架构中,很多系统用的是Oracle这种大型数据库,把整个业务数据放在这样一个强大的数据库里面,利用数据库的参照完整性机制、事务机制,避免出现数据一致性问题。这正是数据库之所以叫“数据库”而不是“存储”的一个重要原因,就是数据库强大的数据一致性保证。


但到了分布式时代,人们对数据库进行了分库分表,同时在上面架起一个个的服务。到了微服务时代,服务的粒度拆得更细,导致一个无法避免的问题:数据库的事务机制不管用了,因为数据库本身只能保证单机事务,对于分布式事务,只能靠业务系统解决。


例如做一个服务,最初底下只有一个数据库,用数据库本身的事务来保证数据一致性。随着数据量增长到一定规模,进行了分库,这时数据库的事务就不管用了,如何保证多个库之间的数据一致性呢?


再以电商系统为例,比如有两个服务,一个是订单服务,背后是订单数据库;一个是库存服务,背后是库存数据库,下订单的时候需要扣库存。无论先创建订单,后扣库存,还是先扣库存,后创建订单,都无法保证两个服务一定会调用成功,如何保证两个服务之间的数据一致性呢?


这样的案例在微服务架构中随处可见:凡是一个业务操作,需要调用多个服务,并且都是写操作的时候,就可能会出现有的服务调用成功,有的服务调用失败,导致只部分数据写入成功,也就出现了服务之间的数据不一致性。


分布式事务解决方案汇总


接下来,以一个典型的分布式事务问题——“转账”为例,详细探讨分布式事务的各种解决方案。


以支付宝为例,要把一笔钱从支付宝的余额转账到余额宝,支付宝的余额在系统A,背后有对应的DB1;余额宝在系统B,背后有对应的DB2;蚂蚁借呗在系统C,背后有对应的DB3,这些系统之间都要支持相关转账。所谓“转账”,就是转出方的系统里面账号要扣钱,转入方的系统里面账号要加钱,如何保证两个操作在两个系统中同时成功呢?


1. 2PC


(1)2PC理论。在讲MySQL Binlog和Redo Log的一致性问题时,已经用到了2PC。当然,那个场景只是内部的分布式事务问题,只涉及单机的两个日志文件之间的数据一致性;2PC是应用在两个数据库或两个系统之间。


2PC有两个角色:事务协调者和事务参与者。具体到数据库的实现来说,每一个数据库就是一个参与者,调用方也就是协调者。2PC是指事务的提交分为两个阶段,如图10-1所示。


  • 阶段1:准备阶段。协调者向各个参与者发起询问,说要执行一个事务,各参与者可能回复YES、NO或超时。

  • 阶段2:提交阶段。如果所有参与者都回复的是YES,则事务协调者向所有参与者发起事务提交操作,即Commit操作,所有参与者各自执行事务,然后发送ACK。


如果有一个参与者回复的是NO,或者超时了,则事务协调者向所有参与者发起事务回滚操作,所有参与者各自回滚事务,然后发送ACK,如图10-2所示。


640?wx_fmt=png

图10-1  2PC事务提交示意图


640?wx_fmt=png

图10-2  事务回滚示意图


所以,无论事务提交,还是事务回滚,都是两个阶段。


(2)2PC的实现。通过分析可以发现,要实现2PC,所有参与者都要实现三个接口:Prepare、Commit、Rollback,这也就是XA协议,在Java中对应的接口是javax.transaction.xa.XAResource,通常的数据库也都实现了这个协议。开源的Atomikos也基于该协议提供了2PC的解决方案,有兴趣的读者可以进一步研究。


(3)2PC的问题。2PC在数据库领域非常常见,但它存在几个问题:


  • 问题1:性能问题。在阶段1,锁定资源之后,要等所有节点返回,然后才能一起进入阶段2,不能很好地应对高并发场景。

  • 问题2:阶段1完成之后,如果在阶段2事务协调者宕机,则所有的参与者接收不到Commit或Rollback指令,将处于“悬而不决”状态。

  • 问题3:阶段1完成之后,在阶段2,事务协调者向所有的参与者发送了Commit指令,但其中一个参与者超时或出错了(没有正确返回ACK),则其他参与者提交还是回滚呢? 也不能确定。


为了解决2PC的问题,又引入了3PC。3PC存在类似宕机如何解决的问题,因此还是没能彻底解决问题,此处不再详述。


2PC除本身的算法局限外,还有一个使用上的限制,就是它主要用在两个数据库之间(数据库实现了XA协议&#x

第1章 课程介绍 介绍该课程的内容、学习成果、实例,还有学习所需的前提知识。 1-1 导学-分布式事务实践 第2章 事务原则与实现 介绍了事务的四大原则,并通过实例介绍数据库实现事务的方法,以及使用JDBC实现事务的方法。 2-1 事务原则与实现:事务 2-2 事务原则与实现:SQL事务 2-3 事务原则与实现:JDBC事务(上) 2-4 事务原则与实现:JDBC事务(下) 第3章 使用Docker搭建环境 介绍了Docker的使用,通过Docker将课程环境搭建起来,方便那些不了解这些技术的同学之后的学习。 3-1 docker简介与mysql安装-1 3-2 docker简介与mysql安装-2 3-3 SpringBoot基础 第4章 Spring事务机制 介绍了Spring的事务机制、事物抽象、内部事务和外部事物,以及常用的几种事务管理的实现,包括DataSource、JPA、JMS、JTA都通过实例进行说明。还有XA以及两阶段提交,并通过实例演示了使用JTA,通过两阶段提交,实现多数据源的事务实现。... 4-1 Spring事务机制_基本接口 4-2 Spring事务机制_实现 4-3 Jpa事务实例 4-4 Jms事务原理 4-5 Jms-session事务实例 4-6 Jms-spring事务实例 4-7 外部事务与JTA 4-8 JTA单数据源事务实例 4-9 JTA多数据源事务实例 第5章 分布式系统 介绍了分布式系统的定义、实现原则和几种形式,详细介绍了微服务架构的分布式系统,并使用Spring Cloud框架演示了一个完整的微服务系统的实现过程。 5-1 CAP原则和BASE理论简介 5-2 分布式系统综述 5-3 SpringCloud微服务架构 5-4 实现registry 5-5 实现proxy 5-6 user服务 5-7 order服务 5-8 添加hystrix 5-9 使用feign 5-10 优化服务间调用 第6章 分布式事务实现,模式和技术 介绍分布式事务的定义、原则和实现原则,介绍使用Spring框架实现分布式事务的几种方式,包括使用JTA、Spring事务同步、链式事务等,并通过实战介绍其实现。除此以外还介绍了一些分布式事务相关的技术,如幂等性、全局一致性ID、分布式对象等。... 6-1 分布式事务介绍 6-2 spring分布式事务实现_使用JTA 6-3 spring分布式事务实现_不使用JTA 6-4 实例1-DB-DB 6-5 实例1-DB-DB.链式事务管理器 6-6 实例2-JPA-DB.链式事务管理器 6-7 实例3-JMS-DB.最大努力一次提交 6-8 分布式事务实现模式与技术 6-9 全局一致性ID和分布式对象_ 第7章 分布式事务实现:消息驱动模式 详细介绍3种分布式事务实现的模式中的消息驱动模式并通过完整实例演示了消息驱动模式下,实现微服务系统的分布式事务的完整过程。 7-1 分布式事务实现:消息驱动模式 7-2 消息驱动模式实例:设计 7-3 消息驱动模式实例:创建ticket服务 7-4 消息驱动模式实例:实现基本ticket功能 7-5 消息驱动模式实例:锁票1 7-6 消息驱动模式实例:锁票2 7-7 按消息流程实现业务 7-8 支付过程 7-9 票转移 7-10 错误处理:锁票失败 7-11 错误处理:扣费失败 7-12 并发时的错误处理 第8章 分布式事务实现:Event Sourcing模式 详细介绍了分布式事务实现的模式中的Event Sourcing模式,并通过完整实例演示了Event Sourcing模式下,实现微服务系统的分布式事务的完整过程。 8-1 事件溯源模式介绍 8-2 事件溯源模式与Axon框架-1 8-3 事件溯源模式与Axon框架-2 8-4 使用Axon框架的设计过程介绍 8-5 Axon框架-实例(上) 8-6 Axon框架-实例(下) 8-7 Saga模式和Axon Saga 8-8 聚合命令事件(上) 8-9 聚合命令事件(下) 8-10 实现saga 8-11 实现query 8-12 处理超时 8-13 并发测试 8-14 cloud-axon实例:分布式处理介绍 8-15 事件设计 8-16 事件与队列设计 8-17 实现User服务 8-18 实现Ticket服务 8-19 实现Order服务 8-20 实现读写分离 8-21 测试与并发 8-22 事件溯源模式与Axon框架总结 第9章 TCC模式和微服务架构的设计模式 本章介绍TCC模式,也对微服务系统的几种设计模式,以及这些模式下分布式事务的实现模式进行了介绍。 9-1 TCC模式介绍 9-2 微服务架构的设计模式 第10章 课程总
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值