-
XA(二阶提交)执行原理
- 准备阶段(Prepare Phase)
- 事务协调者(Transaction Coordinator,TC)向所有参与事务的资源管理器(Resource Manager,RM)发送准备请求。例如,在一个包含数据库 A 和数据库 B 的分布式事务中,TC 会分别向管理数据库 A 和数据库 B 的 RM 发送准备消息。
- RM 接收到准备请求后,会执行本地事务操作,但并不提交。它会将事务执行过程中涉及的数据修改记录到本地的重做日志(Redo Log)和撤销日志(Undo Log)中。以数据库事务为例,它会锁住相关的数据行,执行 SQL 语句(如插入、更新或删除操作),并将这些操作记录下来。如果 RM 执行本地事务操作成功,就向 TC 返回 “准备就绪(Prepared)” 消息;如果执行失败,就返回 “失败(Abort)” 消息。
- 提交阶段(Commit Phase)
- 当 TC 收到所有 RM 返回的 “准备就绪” 消息后,它会向所有 RM 发送提交请求。此时,RM 收到提交请求后,会将本地事务真正提交,即将之前记录在重做日志中的数据修改持久化到数据库中。例如,将更新的数据写入数据文件,释放之前锁住的数据行等操作。
- 如果在准备阶段,有任何一个 RM 返回 “失败” 消息,TC 就会向所有 RM 发送回滚请求。RM 收到回滚请求后,会利用撤销日志中的信息,将已经执行的本地事务操作撤销,恢复到事务开始之前的状态。
- 准备阶段(Prepare Phase)
-
AT 模式执行流程(以 Seata 框架为例)
- 一阶段(执行本地事务)
- 业务代码在执行 SQL 操作时,Seata 框架会拦截这些操作。例如,在一个服务调用多个数据库操作的场景中,当执行插入订单数据到订单数据库和更新库存数据到库存数据库的操作时,Seata 会为每个数据库操作生成一个本地事务。
- 在执行本地事务过程中,Seata 会解析 SQL 语句,获取操作前后的数据镜像(Before Image 和 After Image)。Before Image 是操作前的数据快照,After Image 是操作后的数据快照。这些数据镜像会被保存起来,用于后续可能的回滚操作。同时,本地事务正常执行数据库操作,如插入、更新或删除记录。
- 本地事务执行完成后,Seata 会向事务日志表中插入一条记录,记录这个本地事务的相关信息,包括事务 ID、分支事务类型(这里是 AT 模式)、操作的 SQL 语句等信息。这个事务日志表是 Seata 用于管理分布式事务的关键数据表。
- 二阶段(提交或回滚)
- 提交情况:如果一阶段所有本地事务都执行成功,Seata 会根据事务日志中的记录,异步删除之前保存的 Before Image 和 After Image 数据,因为事务已经成功提交,这些数据快照不再需要。同时,事务日志表中的相关记录也可以在合适的时候被清理,完成整个分布式事务的提交过程。
- 回滚情况:如果在一阶段有本地事务执行失败,或者业务逻辑判断需要回滚事务,Seata 会根据事务日志中的 Before Image 数据,对已经执行的本地事务进行回滚操作。它会将数据库中的数据恢复到 Before Image 记录的状态,从而保证整个分布式事务的一致性。例如,如果在更新库存数据时出现问题,Seata 会利用 Before Image 将库存数据恢复到更新之前的状态,同时清理事务日志中的相关记录。
- 一阶段(执行本地事务)