概述
随着互联网的发展,软件系统由原来的单体应用转变为分布式应用。分布式系统把一个单体应用拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作。这种分布式系统下不同服务之间通过远程协作完成的事务称之为分布式事务,例如用户注册送积分事务、创建订单减库存事务,银行转账事务等都是分布式事务
举个例子,使用传统本地事务完成转账逻辑,任一步骤出问题都会回滚
begin transaction; // 1.本地数据库操作:张三减少金额 // 2.本地数据库操作:李四增加金额 commit transation;
但在分布式系统下,就变成这样
begin transaction; // 1.本地数据库操作:张三减少金额 // 2.远程调用:让李四增加金额 commit transation;
如果执行到第二步,远程调用成功了,李四增加了金额,但因为网络延迟没能及时响应,那么本地系统就会认为事务失败,从而回滚张三减少金额的操作
分布式事务产生的场景
1. 微服务架构
典型的场景就是微服务之间通过远程调用完成事务操作,比如:订单服务和库存服务,下单的同时,订单服务请求库存服务减库存
2. 单体系统访问多个数据库实例
当单体系统需要访问多个数据库时就会产生分布式事务,比如:用户信息和订单信息分别在两个数据库存储,用户管理系统删除用户信息,需要分别删除用户信息及用户订单信息,由于数据分布在不同的数据库,需要通过不同的数据库链接操作数据,产生分布式事务
3. 多服务访问同一个数据库
比如:订单服务和库存服务访问同一个数据库也会产生分布式事务,两个服务持有不同的数据库链接进行操作,产生分布式事务
2PC(两阶段提交)
Two-Phase Commit,两阶段提交,指将整个事务流程分为两个阶段,准备阶段(prepare-phase)、提交阶段(commit-phase)
举例:张三和李四聚餐,饭店老板要求先买单,才能出票,两人就商议 AA。只有张三和李四都付款,老板才能出票安排就餐
- 准备阶段:老板要求张三付款,张三付款,老板要求李四付款,李四付款
- 提交阶段:老板出票,两人拿票就餐
该例形成一个事务,若张三或李四其中一人拒绝付款,或钱不够,老板都不会出票,并且会把已收款退回。整个事务过程由事务管理器和参与者组成,老板就是事务管理器,张三和李四就是事务参与者。事务管理器负责
决策整个分布式事务的提交和回滚,事务参与者负责自己本地事务的提交和回滚
部分关系数据库如 Oracle、MySQL 都支持两阶段提交协议:
- 准备阶段:事务管理器给每个参与者发送 Prepare 消息,每个数据库参与者在本地执行事务,并写本地的 Undo/Redo 日志,此时事务没有提交(Undo 日志记录修改前的数据,用于数据库回滚,Redo 日志记录修改后的数据,用于提交事务后写入数据文件)
- 提交阶段:如果事务管理器收到了参与者的执行失败或者超时消息,直接给每个参与者发送回滚消息;否则,发送提交消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源
XA 规范
2PC 提供了解决分布式事务的方案,但不同的数据库实现却不一样。为了统一标准,国际开放标准组织 Open Group 定义分布式事务的模型(DTP)和 分布式事务协议(XA)
DTP 模型由以下元素组成:
- AP(Application Program):应用程序,可以理解为使用 DTP 分布式事务的程序
- RM(Resource Manager):资源管理器,可以理解为事务的参与者,一般指一个数据库实例,通过资源管理器控制数据库