-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SELECT FOR UPDATE EXECUTOR #1
Comments
code ref apache/incubator-seata-go#478 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
SELECT FOR UPDATE EXECUTOR
the role of executor
众所周知, 为了实现分布式事务在 seata-go 中存在三种角色:
TM
、RM
、TC
。TC
: 事务协调者, 负责维护全局和分支事务的状态, 驱动全局事务提交和回滚TM
: 事务管理器, 负责开启、提交和回滚全局事务, 用户一般是和 TM 打交道RM
: 资源管理器, 管理分支事务处理的资源, 驱动分支事务提交和回滚在一个分布式事务中, 通常涉及多个 RM, 每个 RM 代理一个 DB, TM 会根据业务 SQL 远程调用 RM 开启本地事务并执行 SQL, 同时生成 undo log, 然后 RM 再向 TC 注册分支事务并在 TC 端进行持久化(需要全局锁), 成功以后 RM 再持久化 undo log, 并提交本地事务, 当所有 TM 得到所有 RM 的执行结果以后, 再执行 全局事务的提交 or 回滚
如果执行全局事务的提交, 当所有 RM 负责的分支事务都成功时, TM 则进行全局事务提交, TC 通知所有的 RM 进行第二阶段提交, TC 删除分支事务记录而 RM 删除 undo log, 最终 TC 删除全局事务记录
如果执行全局事务的回滚, 当有至少一个 RM 执行分支事务报错时, TM 只能执行回滚保持全局数据的一致性, 具体做法:TM 通知 TC 进行回滚, TC 则所有 RM 进行回滚, 每个 RM 响应 TC 以后, TC 都会删除对应的全局锁、分支事务, 并更新全局事务状态为 Rollbacked, 然后再删除全局事务
上面说了一堆, 和 executor 有啥关系呢? 实际上 executor 是 RM 的核心之一,负责执行业务 SQL 并生成undo log, 基本上它是第一阶段的全部内容, 从开启本地事务到执行分支业务 SQL 到最后提交本地事务
select for update
总结: for update 会给查询到的记录加锁(行锁 or 表锁),在RR级别下防止幻读
select for update executor implementation
在 RM 中,executor 先开启本地事务,并执行业务 SQL,然后分析业务 SQL 中的主键
Q & A
01 为什么需要全局锁锁住这些记录呢, for update 不是已经锁住了记录吗?
executor 负责开启本地事务、执行业务 SQL 和 提交事务, 在该 RM 执行完分支业务 SQL 后,会提交本地事务,for update 加的锁已经释放了,如果存在其他 RM 修改这部分记录,就需要全局锁,等所有 RM 执行完所有分支事务以后再一个个的释放 全局锁
02 上文提到 RM 会执行业务 SQL 并生成 undo log, 但实现中貌似没有 undo log?
是的,因为 select for update 只是对记录加锁,并没有修改数据,并不需要回滚
03 在分布式事务场景上, 存在使用该 executor 的场景吗?
待补充
04 怎么分析这条 SQL 语句存在主键,以及如何锁住这些记录?
如何分析:实现在 buildSelectPKSQL 方法中,具体做法就是通过这个 table 的 meta 信息拿到所有的主键,然后复用这条查询 SQL 的 SelectStmt 将 fileds 换成 主键即可, 生成新的 SQL newsql
如何锁住:执行 newsql,并将结果放到拼成一个 key,存储到 TC 中 (todo:待PR合入,贴下代码)
reference
The text was updated successfully, but these errors were encountered: