1. 分布式事务
分布式事务就是一个业务操作,由多个细分操作完成,这些细分操作又分布在不同的服务器上;事务,就是这些操作要么全部成功执行,要么全部不执行。
2. 分布式事务产生的原因
伴随着系统拆分出现,分布式系统解决了海量数据服务对扩展性的要求,但是增加了架构上的复杂性,分布式事务就是典型的体现。实际开发中,分布式事务产生的原因主要来源于存储和服务的拆分。
2.1 存储层拆分
最典型的就是数据库分库分表,一般来说,当单表容量达到千万级,就要考虑数据库拆分,从单一数据库变成多个分库和多个分表。在业务中如果需要进行跨库或者跨表更新,同时要保证数据的一致性,就产生了分布式事务问题。
2.2. 服务层拆分
业务的服务化,系统架构的演进是从集中式到分布式,业务功能之间越来越解耦合。
比如电商网站系统,业务初期是一个单体工程支撑整套服务,随着系统规模进一步变大,将核心业务抽取出来,以作为独立的服务。商品、订单、库存、账号信息都提供了各自的服务,业务逻辑的执行散落在不同的服务器上。
用户在某网站上进行一个下单操作。会同时依赖订单服务、库存服务、支付扣款服务,这几个操作如果有一个失败,下单操作也就完不成,这就需要分布式事务来保证。
3. 分布式事务解决方案
典型的有两阶段和三阶段提交协议、 TCC 分段提交,和基于消息队列的最终一致性设计。
3. 1PC 两阶段提交
非常经典的强一致性、中心化的原子提交协议,在各种事务和一致性的解决方案中,都能看到两阶段提交的应用。
3. 2 PC 三阶段提交
在 2PC 之上扩展的提交协议,主要是为了解决两阶段提交协议的阻塞问题,从原来的两个阶段扩展为三个阶段,增加了超时机制。
3.3 TCC 分段提交
TCC 是一个分布式事务的处理模型,将事务过程拆分为 Try、Confirm、Cancel 三个步骤,在保证强一致性的同时,最大限度提高系统的可伸缩性与可用性。
3.4. 基于消息补偿的最终一致性
基于消息队列的最终一致性是一种异步事务机制,在业务中广泛应用。主要有本地消息表和第三方可靠消息队列等来具体实现。
本地消息表:核心思想是将分布式事务拆分成本地事务进行处理,通过消息日志的方式来异步执行。是一种业务耦合的设计,消息生产方需要额外建一个事务消息表,并记录消息发送状态,消息消费方需要处理这个消息,并完成自己的业务逻辑,另外会有一个异步机制来定期扫描未完成的消息,确保最终一致性。通过下单减库存业务来简单模拟本地消息表的实现过程:
(1)系统收到下单请求,将订单业务数据存入到订单库中,并且同时存储该订单对应的消息数据,比如购买商品的 ID 和数量,消息数据与订单库为同一库,更新订单和存储消息为一个本地事务,要么都成功,要么都失败。
(2)库存服务通过消息中间件收到库存更新消息,调用库存服务进行业务操作,同时返回业务处理结果。
(3)消息生产方,也就是订单服务收到处理结果后,将本地消息表的数据删除或者设置为已完成。
(4)设置异步任务,定时去扫描本地消息表,发现有未完成的任务则重试,保证最终一致性。