1.架构图
TM(Transaction Manager)发送提交/回滚命令
这个模块是全局事务管理器,负责开启全局事务、提交全局事务、回滚全局事务、查询全局事务的状态、上报本地事务状态等。(TransactionManager.java)
RM(Resource Manager)执行提交/回滚操作
这个是资源管理器,负责分支事务注册、分支事务提交、分支事务回滚、锁查询等操作。(DefaultResourceManager.java)
TC (Transaction Coordinator) 用于接收提交/回滚
事务的协调者。也可以看做是 Seata-server,用于接收我们的事务的注册,提交和回滚
实际上RM才是真正处理事务操作的地方
2.AT模式
检查方法是否携带@GroblaTransaction注解,存在开启全局事务
2.1执行本地事务
1.开启全局事务,并且获取Xid全局事务id
2.执行本地事务的代码(business.excute),执行过程中被seata的代码监管
3. commitGlobalTransaction/rollbackGlobalTransaction 提交当前分支事务,回滚当前分支事务
4. 执行一些托管到 TransactionHookManager 中的 complete hook 逻辑
5. 复原由事务传递属性改变的当前事务的状态,比如 REQUIRES_NEW 传递属性就将当前分布式事务 xid 挪走了,这一步 就讲 xid 重新放到当前线程的上下文中。
2.2执行全局commit
1. 关闭全局事务的状态,并将全局事务的状态设置为开始提交
2. 根据分布式事务的模式(AT、TCC、SAGA)选择是同步提交还是异步提交。目前只有 TCC 要求交操作是同步的,其它 的模式是异步提交全局事务。
3. 执行事务提交操作,异步则是将全局事务状态更新为 AsyncCommitting,更新到数据库,后面有由定时任务重新拉起, 执行同步提交事务;
同步提交事务,查询到当前全局事务下所有的分支事务,通知客户端提交分支事务,如果失败,则将状态更新为 CommitRetrying,由另一个线程反复重试,直到成功为止
2.2执行全局rollback
2.3隔离级别
2.3.1写隔离
写隔离的实现基本步骤:
•一阶段本地事务提交前,需要确保先拿到全局锁 。
•拿不到全局锁,不能提交本地事务。
•拿全局锁的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁
2.3.1读隔离
Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted) 。
如果应用在特定场景下,必需要求全局的 读已提交 ,目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理。这个代理在读之前,先去获取全局锁,获取不到则一直重试。
3.TCC模式
3.1基本原理
两阶段提交:
1. 执行 prepare 方法,锁定资源
2. 执行 Commit 或者 Rollback 方法,根据锁定资源的情况决定是提交事务还是回滚事务。
3.2常见问题
空回滚
空回滚就是 TCC 还没有执行 Prepare 方法,就已经执行了第二阶段的 Cancel 方法
幂等
幂等就是对于同一个分布式事务的同一个分支事务,重复去调用该分支事务的第二阶段接口,因此,要求 TCC 的二阶段 Confirm 和 Cancel 接口保证幂等,不会重复使用或者释放资源。