3.8 KiB
seata
seata作为兼具高性能和易用性的分布式事务解决方案,适用于微服务架构。
在使用seata的系统中,事务隔离级别如下:
branch transaction/local transaction:在seata系统中,分支事务/本地事务的隔离级别为read committedglobal transaction:在seata系统中,全局事务的隔离级别为read uncommittedglobal transaction隔离级别为read uncommitted的含义如下:在全局事务尚未提交时,如果分支事务提交,则分支事务的修改对分布式系统外的其他事务可见
故而,在分布式系统中,若全局事务的隔离级别为read uncommitted,且没有其他机制用于修复该问题,其将会造成如下问题:

在上图所示中,全局事务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中,RM(Resource Manager)module将会在需要获取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
- doBranchRegister:branch transaction注册
- 在AT中,branch register会在local transaction提交时进行,执行brach register时会实际占用global exclusive write lock
- doLockCheck:global 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
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的释放,这种等待会带来性能损耗。