doc: 阅读seata global exclusive write lock相关的文档

This commit is contained in:
asahi
2025-08-26 19:28:59 +08:00
parent b649c1ec0c
commit 44f2a8c540
3 changed files with 51 additions and 54 deletions

View File

@@ -1,22 +0,0 @@
# 分布式事务: Saga模式
## Saga模型
- 每个Saga都由一系列子事务Ti组成
- 每个子事务Ti都有其对应的补偿动作Ci补偿操作用于对Ti操作产生的结果进行撤销
## Saga的执行顺序
1. T1, T2, T3, ... ,Tn全部执行成功
2. T1 T2, T3, ..., Tj, Cj, Cj-1,... , C1 (执行出错之后回滚之前所有成功的子事务)
## 执行出错时Saga的恢复策略
1. 向后恢复backword recovery对所有已经完成的子事务进行补偿操作任一子事务Ti执行失败撤销掉之前所有执行成功的子事务使得整个Saga的执行结果都撤销
2. 向前恢复forward recovery重新尝试失败的事务。假设每个事务最终都会执行成功。其执行顺序为T1, ... Tj(失败), Tj重试,...,...,Tn。该种情况下并不需要Ci操作对子事务Ti的操作结果进行撤销
## Saga模式的结构
Saga的嵌套结构只允许存在两个层次
1. 顶层的Saga
2. 简单的子事务
## Saga特性
- 在外层各个Sagas都在执行时各个Sagas在执行过程中已经提交的子事务Ti其执行结果对其他Sagas可见隔离性并无法被满足Sagas可能看到其他Sagas的执行结果
- 每个子事务都是一个独立事务,各个子事务为独立的原子行为
## Saga ACID
- 原子性:正常情况下可以保证
- 一致性执行过程中可能会有A库和B库违反一致性要求的情况但是最终成功之后是一致的
- 隔离性Sagas A能看到Sagas B部分执行的执行结果
- 持久性对于Sagas中的子事务Ti其执行完成之后就会commit而其撤销操作则是会调用Ci对已经提交的操作进行撤销操作

View File

@@ -1,32 +0,0 @@
# 分布式事务: TCC模式
## TCC事务
TCC是Try、Confirm、Cancel三个单词的首字母缩写TCC分为三个阶段预处理Try、确认Confirm、撤销Cancel
## TCC工作流
## 预处理阶段Try phase
在预处理阶段,请求者会请求服务的提供者做一些尝试性的操作。在该阶段,服务提供者会完成一些业务检查与验证,并且预占需要的业务资源。
## 确认阶段Confirm phase
- 如果服务提供者成功执行了Try阶段并且请求者决定继续执行操作那么请求者可以在确认阶段执行确认操作。
- ***具体的业务在确认阶段被执行***。
- 在确认阶段不会执行更多的验证操作所有验证操作都会在Try阶段执行
- 在Confirm阶段只会使用Try阶段预留的业务资源
> 通常认为Confirm阶段是不会执行失败的如果Try阶段被成功执行那么Confirm阶段也能成功执行如果Try成功而Confirm执行失败会对Confirm阶段进行重试
## 撤销阶段Cancel phase
在撤销阶段如果Try阶段未正确完成且请求者决定不再继续执行请求者可以在服务提供者上执行撤销操作。在Try阶段预占的业务资源应该在撤销阶段被正确释放
***撤销阶段Cancel是对预处理阶段Try的反向操作***
## TCC事务
对于TCC事务全局事务管理器首先会发起所有分支事务的Try操作
- 若任何一个分支事务的Try操作执行失败都会导致所有分支事务的Cancel操作被执行
- 若所有分支事务的Try操作都执行成功那么全局事务管理器会发起所有分支事务的Confirm操作
在执行分支事务Confirm/Cancel操作时如果执行失败那么全局事务管理器会对失败操作进行重试
> 通常Cancel阶段也被认为是一定执行成功的如果在Cancel执行时发生错误需要进行重试或进行人工处理
## TCC事务中需要注意的要点
### 空回滚
若是在没有调用TCC Try阶段的情况下直接调用二阶段的Cancel方法Cancel方法需要识别出之前并未调用过Try阶段方法直接返回Cancel成功
### 幂等
由于在各阶段执行时都存在重试机制故而要保证Try、Confirm、Cancel接口都要保证幂等性保证占用资源或释放资源的操作不会被重复执行
### 悬挂
在RPC调用过程中由于网络拥堵等原因Cancel操作可能先于Try操作执行。
> 1. 如果先调用Try时网络拥堵发生超时那么TM会通知RM回滚分布式事务调用Cancel操作
> 2. 因为网络拥堵可能调用完Cancel后RPC的Try请求才到来
> 3. 此时到来的Try请求会预留资源而预留资源无法被其他事务所使用

View File

@@ -0,0 +1,51 @@
# 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
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的释放这种等待会带来性能损耗。