上海阔达网站建设公司,类似云盘 网站开发,知名个人网站,松岗专业做网站公司Seata源码学习引入
学习了Seata的应用以后#xff0c;我们从这开始要开始分析Seata的源码相关内容
源码下载
官方地址#xff1a;https://seata.io/zh-cn/blog/download.html 通过idea打开seata-1.4.2版本的源码 回顾AT模式
其实在之前的应用课程中#xff0c;我们已经用…Seata源码学习引入
学习了Seata的应用以后我们从这开始要开始分析Seata的源码相关内容
源码下载
官方地址https://seata.io/zh-cn/blog/download.html 通过idea打开seata-1.4.2版本的源码 回顾AT模式
其实在之前的应用课程中我们已经用过AT模式同时也写过一个小的Demo那么这里其实我们主要要分析的是AT模式官方文档中的一些内容
官方文档https://seata.io/zh-cn/docs/dev/mode/at-mode.html
写隔离
一阶段本地事务提交前需要确保先拿到 全局锁 。拿不到 全局锁 不能提交本地事务。拿 全局锁 的尝试被限制在一定范围内超出范围将放弃并回滚本地事务释放本地锁。
图解 如果 tx1 的二阶段全局回滚则 tx1 需要重新获取该数据的本地锁进行反向补偿的更新操作实现分支的回滚。
此时如果 tx2 仍在等待该数据的 全局锁同时持有本地锁则 tx1 的分支回滚会失败。分支的回滚会一直重试直到 tx2 的 全局锁 等锁超时放弃 全局锁 并回滚本地事务释放本地锁tx1 的分支回滚最终成功。
因为整个过程 全局锁 在 tx1 结束前一直是被 tx1 持有的所以不会发生 脏写 的问题。
读隔离
在数据库本地事务隔离级别 读已提交Read Committed 或以上的基础上SeataAT 模式的默认全局隔离级别是 读未提交Read Uncommitted 。
如果应用在特定场景下必需要求全局的 读已提交 目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理。
图解 SELECT FOR UPDATE 语句的执行会申请 全局锁 如果 全局锁 被其他事务持有则释放本地锁回滚 SELECT FOR UPDATE 语句的本地执行并重试。这个过程中查询是被 block 住的直到 全局锁 拿到即读取的相关数据是 已提交 的才返回。
出于总体性能上的考虑Seata 目前的方案并没有对所有 SELECT 语句都进行代理仅针对 FOR UPDATE 的 SELECT 语句。
AT二阶段
一阶段
1. 解析 SQL得到 SQL 的类型UPDATE表product条件where name ‘TXC’等相关的信息。
查询前镜像改变之前的数据根据解析得到的条件信息生成查询语句定位数据。执行业务 SQL更新这条数据。查询后镜像改变后的数据根据前镜像的结果通过 主键 定位数据。插入回滚日志把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录插入到 UNDO_LOG 表中。提交前向 TC 注册分支申请 全局锁 。本地事务提交业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。将本地事务提交的结果上报给 TC。
二阶段-回滚
收到 TC 的分支回滚请求开启一个本地事务执行如下操作。通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句提交本地事务。并把本地事务的执行结果即分支事务回滚的结果上报给 TC。
二阶段-提交
收到 TC 的分支提交请求把请求放入一个异步任务的队列中马上返回提交成功的结果给 TC。 的结果上报给 TC。
二阶段-提交
收到 TC 的分支提交请求把请求放入一个异步任务的队列中马上返回提交成功的结果给 TC。异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。