分布式事务原理

Published on in 架构设计 with 14,711 views and 4 comments

本文是对分布式事务原理、规范的科普,主要围绕两阶段提交协议展开。最后描述了在应用框架层面模拟两阶段提交协议的简化设计。

1 事务/分布式事务

1.1 事务

事务是数据库从一个稳定状态变迁到另一个稳定状态的保证,具备 ACID 这 4 个特性:

  • 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态。
  • 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性限制没有被破坏。
  • 隔离性(Isolation):两个事务的执行是互不干扰的,两个事务时间不会互相影响。
  • 持久性(Durability):在事务完成以后,该事务对数据库所作的更改便持久地保存在数据库之中,并且是完全的。
例如应用程序需要更新多条相关数据时就需要进行事务处理。
 

1.2 分布式事务与 XA 规范

分布式事务是指会涉及到操作多个数据库的事务,同样必须保证 ACID。
其就是将对同一库事务的概念扩大到了对多个库的事务:对同一库的 SQL 操作对应了分布式事务中对一个库的事务。
 
X/Open XA 定义了分布式事务处理的规范,并由数据库厂商在驱动层面进行实现。XA 规范的基础是两阶段提交协议,并定义了分布式事务处理所涉及的角色:
  • 应用程序(AP)
  • 事务管理器(TM)
  • 资源管理器(RM)
  • 通信资源管理器(CRM)
可以这样认为,事务管理器即事务处理中间件(分布式事务处理系统);资源管理器即各个数据库。

2 两阶段提交协议

两阶段提交协议(Two-phase commit protocol, 2PC)将一次分布式事务处理划分为两个阶段:预提交阶段(也称为准备阶段或投票阶段),提交阶段。

2.1 预提交阶段

这是两阶段提交协议的第一个阶段,分布式事务处理系统咨询各个资源管理器是否可以提交本地事务,各个资源管理器会把这个咨询过程写入日志,以便进行回滚或提交。

 

当一个数据库接收到咨询后,它会将需要执行的操作写入日志,禁止其他写入操作(锁定资源)。

如果分布式事务中某数据库预提交失败或提交失败,那该数据库会根据日志进行自身的操作回滚,并解锁。

2.2 提交阶段

分布式事务处理系统对各个资源管理器下达提交/回滚的指令,使整个分布式事务结束。

 

当一个数据库接受到提交/回滚指令时,它将根据第一阶段的日志进行提交/回滚处理。

 

两阶段提交协议可以在数据库层面通过驱动支持,也可以在应用框架中按照其原理进行设计实现。

3 分布式事务应用框架

使用数据库驱动方式实现两阶段事务有两个不足:

  • 随着分布式事务的参与者增多,效率会明显降低
  • 对应用开发者透明,调试不便
  • 必须依赖数据库,不是所有数据库都实现了 XA 规范

3.1 角色

  • 发起者:分布式事务发起者,需要提供回查恢复接口
  • 参与者:参与到分布式事务的其他系统,提供提交/回滚接口。这里的提交/回滚接口即是对数据库数据的 SQL 操作。
  • 活动管理器:负责管理分布式事务(活动、操作)。
  • 定时器:触发对分布式事务活动的捞取,以备回查恢复。

3.2 交互时序

两阶段提交时序:

两阶段提交时序
 
 
因为系统在上述交互中不是绝对可靠的,所以需要一定的方式进行事务状态恢复,保证所有参与者最终一致。

回查恢复时序:

回查恢复时序

3.3 关键点

  • 参与者提供的提交/回滚接口必须满足幂等性,即定时触发重复调用提交/回滚时不会重复操作同一资源
  • 根据发起者生成 txId,回查恢复时根据 txId 调用发起者回查恢复接口
  • 活动管理器与发起者同库/不同库时,事务活动、操作状态变迁的不同处理
  • 事务内调用操作的顺序
  • 定时任务定时间隔/重试次数

参考

 

---- EOF ----

Responses
  • lorne

    www.txlcn.org 开源的分布式事务框架 支持springcloud dubbo

    Reply
  • 分享一个在电商购物支付流程中,在各大参与者系统中可能会遇到分布式事务问题的场景及对应的解决方案
    http://www.roncoo.com/article/detail/124243

    Reply
  • 林思锐

    有兴趣可以加群讨论:472213887

    Reply
  • 呵呵,比较难,纯占位。

    Reply