Files
rikako-note/分布式事务/seata/seata.md
2025-08-26 19:32:45 +08:00

60 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- [seata](#seata)
- [Seata Global Exclusive Write Lock](#seata-global-exclusive-write-lock)
- [TC - Global Exclusive Write Lock Implementation](#tc---global-exclusive-write-lock-implementation)
- [RM - Global Exclusive Write Lock Usage](#rm---global-exclusive-write-lock-usage)
# seata
seata作为兼具高性能和易用性的分布式事务解决方案适用于微服务架构。
在使用seata的系统中事务隔离级别如下
- `branch transaction`/`local transaction`在seata系统中分支事务/本地事务的隔离级别为read committed
- `global transaction`在seata系统中全局事务的隔离级别为read uncommitted
- `global transaction`隔离级别为read uncommitted的含义如下在全局事务尚未提交时如果分支事务提交则分支事务的修改对分布式系统外的其他事务可见
故而在分布式系统中若全局事务的隔离级别为read uncommitted且没有其他机制用于修复该问题其将会造成如下问题
<img src="https://yqintl.alicdn.com/3588613a02db62c2b534a61984145bbdc6394811.png" alt="1" title="1">
在上图所示中全局事务A和全局事务B对相同的资源R进行了修改并且分支事务A1和分支事务B1都本地提交之后全局事务A回滚全局事务B提交那么A无法将资源R回滚到一个合适的状态例如A1先对R进行修改B1后对R进行修改如果将R恢复到A1修改之前那么B1对R的修改就会丢失
## Seata Global Exclusive Write Lock
`Seata Global Exclusive Write Lock`的代码实现位于`TC`(Transaction Coordinator) module中RMResource Managermodule将会在`需要获取global lock`时对TC module进行请求进而保证事务之间的写隔离。
故而Seata Global Exclusive Write Lock会在TC module中被实现并在RM module中被使用。
## TC - Global Exclusive Write Lock Implementation
在TC module中RpcServer用于处理communication protocol related logic而TC module实际的处理逻辑则由`DefaultCoordinator`进行处理。
> `DefaultCoordinator`中包含了TC module所有向外暴露的方法例如
> - doGlobalBegin: 创建全局事务
> - doGlobalCommit: 提交全局事务
> - doGlobalRollback: 全局事务回滚
> - doBranchReport: branch transaction状态report
> - doBranchRegisterbranch transaction注册
> - 在AT中branch register会在local transaction提交时进行执行brach register时会实际占用global exclusive write lock
> - doLockCheckglobal exclusive write lock校验
>
> 实际上,上述方法都会被委托给`DefaultCore`来执行
在TC端的实现中所有`获取锁``校验锁`的请求都最终会被`LockManger`执行所有关于global exclusive write lock的设计都被维护在DefaultLockManagerImpl中。
## RM - Global Exclusive Write Lock Usage
在RM module中主要会使用两个global write lock相关的方法
- 校验是否global lock可以被获取
- 注册transaction branch并实际获取global lock
> 在RM端针对global exclusive write lock的check和获取大多通过Statement和Connection的代理对象来实现。例如在`ConnectionProxy.commit`中调用`registerBranch`从而实现对lock的实际占用。
global write lock的释放和RM无关当全局事务提交时全局事务相关的global lock将会自动被TC module释放。当注册分支事务之前会检查global lock状态确定在branch register的过程中不会发生锁冲突。
当执行update、insert、delete语句时在执行前后都会以undo log的形式生成data snapshot并且生成快照的形式会基于`select ... for update`
在本地事务执行提交操作时会执行branch register操作该操作中会向TC module发送请求要求占用global write lock。
故而通过global write lock机制seata能够保证全局事务未提交前分支事务占用的锁资源并不会被释放全局事务外的其他事务想要访问数据时首先需要校验是否global exclusive write lock已经被占用上述流程能够保证全局事务能够正确的回滚。
但是在全局事务提交前其他事务必须等待global exclusive write lock的释放这种等待会带来性能损耗。