了解 Seata 的实现原理吗?
了解 Seata 的实现原理吗?
回答重点
Seata 主要通过三大核心组件来协调全局事务的执行。
事务协调器(Transaction Coordinator,TC):TC 负责管理全局事务的生命周期,记录全局事务和分支事务的状态,并协调全局事务的提交和回滚。TC 是 Seata 的中心控制器,所有的分布式事务请求都会通过 TC 进行管理。
- 作用:TC 保证各个分支事务在全局事务中的状态一致性。它记录每个事务分支的状态信息,并在发生异常时向相关分支发送回滚命令。
事务管理器(Transaction Manager,TM):TM 负责定义全局事务的边界,即启动、提交、回滚全局事务。TM 通常嵌入在业务服务中,用于向 TC 发起全局事务的创建和提交请求。
- 作用:通过
@GlobalTransactional注解或 API,TM 标记某个业务操作为全局事务。TM 在业务逻辑执行过程中负责与 TC 通信,以确定事务的最终状态。
资源管理器(Resource Manager,RM):RM 负责管理本地资源(如数据库),以及分支事务的注册、提交、回滚。RM 的核心作用是对本地数据库进行事务操作,并将分支事务的状态通知给 TC。
- 作用:在分支事务执行时,RM 通过数据库代理层来记录数据快照,以便在事务回滚时能够还原数据。同时,RM 负责向 TC 注册分支事务,并在接收到 TC 的命令时执行数据的提交或回滚操作。
大致流程简述如下:
- TM 向 TC 发起全局事务创建,TC 返回 XID。
- TM 调用业务方法,业务方法执行过程中,RM 向 TC 注册分支事务。
- RM 执行数据库操作并生成回滚日志,同时提交本地事务。
- 业务方法执行结束后,TM 向 TC 发送全局提交或回滚请求。
- TC 收到请求后,通知 RM 执行提交或回滚操作。
- RM 执行提交或回滚,并将结果通知 TC。
- TC 记录事务状态为提交完成或回滚完成。
Seata 的事务模式
- AT 模式(Automatic Transaction):AT 模式是 Seata 最具代表性的事务模式。它通过自动代理数据库操作,在事务提交前生成回滚日志(其它模式不需要),以便在需要回滚时恢复数据。Seata 在本地事务提交时,通过
undo_log表记录数据快照,实现数据的原子性回滚。 - TCC 模式(Try-Confirm-Cancel):TCC 模式将业务操作拆分为三个步骤:Try(预留资源)、Confirm(确认操作)、Cancel(回滚操作)。每个步骤都由业务开发者手动实现,Seata 负责协调这些步骤的执行和回滚,适合对资源控制要求高的场景。
- SAGA 模式:SAGA 模式是一种长事务模式,将全局事务拆解为多个有序的小事务,每个小事务都有相应的补偿操作。SAGA 适合处理跨多个服务的复杂业务流程,通过补偿机制来保证数据的一致性。
- XA 模式:Seata 提供的 XA 模式基于两阶段提交协议(2PC),能够保证全局事务的强一致性。TC 作为协调者管理各个参与者的提交和回滚操作,但这种模式性能较低,适合对一致性要求严格的场景。
扩展知识
Seata 的事务执行流程
Seata 的事务执行流程主要包括 全局事务的创建、分支事务的注册、事务的提交或回滚 等步骤。具体流程如下:
全局事务的创建(Transaction Start)
事务管理器(TM) 通过在业务方法上使用 @GlobalTransactional 注解,标识该方法为全局事务。业务方法调用时,TM 会向 事务协调器(TC) 发起全局事务的创建请求。
TC 负责为该全局事务生成一个唯一的 全局事务 ID(XID),并返回给 TM。XID 是全局事务的唯一标识,用于后续跟踪和管理这个事务的所有操作。
分支事务的注册(Branch Register)
分支事务 是全局事务的一部分,通常对应业务方法中具体的数据库操作(如新增、更新、删除)。
业务方法 执行时,会调用数据库操作(如 INSERT、UPDATE)。Seata 的 资源管理器(RM) 通过代理数据库操作来记录数据的前后状态,并生成回滚日志。
在执行数据库操作之前,RM 会将该数据库操作注册为分支事务,并向 TC 发起分支注册请求。
注册信息包括:
- 全局事务 ID(XID)
- 资源 ID(如数据库表名)
- 分支事务的类型(如 AT 模式的 SQL 操作)
- 数据的锁定信息(用于行锁管理)
TC 接收到分支事务注册请求后,会记录该分支事务的信息,并将注册成功的结果返回给 RM。
业务方法的执行与本地事务提交(Local Transaction Commit)
分支事务注册成功后,RM 执行数据库操作,更新数据并将修改的状态保存到数据库中。
在完成操作后,本地事务提交,此时本地事务的数据已经写入数据库,但全局事务尚未提交。为了支持回滚,回滚日志(undo_log) 也会存储在数据库中,以记录数据修改前的状态。
全局事务的提交或回滚(Global Commit/Rollback)
在业务逻辑执行完成后,全局事务会进入提交或回滚的阶段,具体流程如下:
全局提交流程:
- 如果业务逻辑正常执行,TM 向 TC 发起全局提交请求。
- TC 根据 XID 确认所有分支事务状态正常后,向所有参与的 RM 发送分支提交请求。
- RM 接收到分支提交请求后,执行数据库操作的最终提交(实际上,AT 模式下的数据已经在本地事务阶段提交,分支提交请求主要是确认无误)。
- TC 收到所有分支提交成功的响应后,标记全局事务为提交完成,并释放全局锁。
全局回滚流程:
- 如果业务逻辑执行过程中发生异常,TM 向 TC 发起全局回滚请求。
- TC 向所有参与的 RM 发送分支回滚请求。
- RM 在接收到分支回滚请求后,根据
undo_log中记录的数据快照,将数据库恢复到执行操作之前的状态,确保数据一致性。 - TC 收到所有分支回滚完成的响应后,标记全局事务为回滚完成,并释放相关的全局锁。
全局事务的结束(Transaction End)
无论是全局事务的提交还是回滚,当 TC 确认所有分支事务的操作完成后,会标记该全局事务的状态为 COMMITTED 或 ROLLED BACK,并在事务日志中记录事务的结束状态。
事务结束后,Seata 会清理 undo_log 表中的数据,防止日志表占用过多的数据库存储空间。
Seata 的数据一致性保证机制
- 回滚日志机制(Undo Log):在 AT 模式下,Seata 会在本地事务执行前后记录
undo_log,即数据操作前的快照信息。回滚时,Seata 读取undo_log并恢复数据,确保事务回滚操作的正确性。 - 全局锁机制:Seata 使用全局锁来管理分支事务对数据库行的并发访问,确保同一行数据在同一时刻只能被一个全局事务修改。通过 TC 管理全局锁,可以防止多事务并发修改同一数据行时的冲突。
- 两阶段提交(2PC):Seata 的事务提交过程遵循两阶段提交协议:第一阶段:RM 提交本地事务,同时记录
undo_log,注册分支事务到 TC。第二阶段:TC 根据全局事务的状态决定提交或回滚,并通知所有 RM 执行相应操作。