Seata服务端开启事务核心源码解析
文章目录
- 概述
- 一、doGlobalBegin
- 1.1、createGlobalSession
- 1.2、addSessionLifecycleListener
- 1.3、begin
概述
Seata服务端作为TC角色,用于接收客户端标注了@GlobalTransactional
也就是TM角色的开启事务,提交/回滚事务请求,维护全局和分支事务的状态,并驱动客户端的RM角色真正地去执行开启事务,提交/回滚事务操作。
服务端与客户端交互的类,是AbstractTCInboundHandler
在TCInboundHandler
顶级接口中,定义了开启,提交/回滚事务的统一处理模板,接收客户端的请求:
AbstractTCInboundHandler
重写了各自的handle方法,加入了自己的处理逻辑,实际上也是委托子类DefaultCoordinator
去完成具体的逻辑的。
一、doGlobalBegin
doGlobalBegin
是Seata服务端处理TM开启全局事务请求的方法:
调用到了DefaultCore
的begin
方法:
- 创建一个
GlobalSession
对象,表示当前全局事务的上下文。(GlobalSession是Seata中用于管理一个全局事务生命周期的核心对象。) - 将 XID 放入日志上下文。
- 注册一个监听器,用于监听事务开始、结束、提交、回滚等生命周期事件。
- 正式启动事务,记录开始时间、生成 XID、持久化到存储(例如写入文件或数据库)。
- 向客户端返回 XID,客户端后续注册分支事务、提交、回滚时会携带它。
1.1、createGlobalSession
最终会调用到GlobalSession
,主要是给GlobalSession
的一些属性赋值,同时XID就是在这一步生成的。
1.2、addSessionLifecycleListener
主要是向lifecycleListeners
集合中添加监听器。
SessionManager
是SessionLifecycleListener
的子类,定义了不同时机被触发的事件的模板,具体的实现有数据库、文件、Redis。
1.3、begin
在begin
方法中,首先会记录当前的状态为开始,同时记录开始时间,后续判断超时。然后会调用监听器的onBegin
方法(onBegin
方法是SessionManager
父类的)
选择DataBaseSessionManager
的addGlobalSession
实现:
该方法的作用是,把事务会话持久化到数据库中。首先会判断taskName是否为空,当 Seata 正常处理事务时,taskName 是空的。如果是异步任务/重试任务,taskName 不为空。
然后会根据不同的操作类型,执行不同的数据库操作:
以insertGlobalTransactionDO
为例,根据当前数据库类型和表名,获取SQL:
事务开启时,向global_table
中初始化一条数据,执行如下的SQL:
insert into global_table (xid,transaction_id,status,application_id,transaction_service_group,transaction_name,timeout,
begin_time,application_data,gmt_create,gmt_modified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, now(), now())