- [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,且没有其他机制用于修复该问题,其将会造成如下问题: 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中,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 > 在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的释放,这种等待会带来性能损耗。