Seata 是一款阿里开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案,github地址:https://github.com/seata/seata。
关于分布式事务模式,seata可分为如下几种:
Auto Transaction
,基于支持本地ACID事务的关系型数据库,对业务无侵入;Manual Transaction
,不依赖于底层数据资源的事务支持,需自定义prepare/commit/rollback
操作,对业务有侵入;由于目前seata场景中使用AT模式较多,因此本文主要分析AT模式流程。
AT模式的前提是基于支持本地 ACID 事务的关系型数据库和Java应用基于JDBC访问数据库。AT模式是二阶段提交协议的演变:
写隔离保证是通过全局锁来保证的,一阶段事务提交前必须要拿到全局锁,否则不能提交本地事务,获取全局锁过程中不能无限等待,超时后放弃,并回滚本地事务,释放本地锁(避免产生死锁)。
这里思考下,插入操作该如何保证写隔离呢?其实插入操作中也是需要获取全局锁的,毕竟分布式事务中分支插入数据后,全局事务未commit时该插入数据不能被其他事务修改。
比如两个全局事务tx1和tx2,分别对a表的m字段做更新操作,m初始值1000。tx1先开始,开启本地事务拿到本地锁,更新操作 m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的 全局锁 ,本地提交释放本地锁。tx2 后开始,开启本地事务,拿到本地锁,更新操作 m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的 全局锁 ,tx1 全局提交前,该记录的全局锁被 tx1 持有,tx2 需要重试等待 全局锁 。此时会有以下两种情况:
在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted),因为分支事务在阶段一就已经提交了,如果其他分支事务还未提交,那么从已提交事务的数据库读取数据能看到更新后的数据,因为此时全局事务还未全部提交,所以是未提交读。
如果应用在特定场景下,必须要求全局的 读已提交 ,目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理:
SELECT FOR UPDATE
语句的执行会申请 全局锁 ,如果 全局锁 被其他事务持有,则释放本地锁(回滚 SELECT FOR UPDATE
语句的本地执行)并重试。这个过程中,查询是被 block 住的,直到 全局锁 拿到,即读取的相关数据是 已提交 的,才返回。出于总体性能上的考虑,Seata 目前的方案并没有对所有 SELECT 语句都进行代理,仅针对 FOR UPDATE 的 SELECT 语句。
一阶段:
一阶段在分支事务提交前向TC注册分支,进行一次通信。
二阶段-回滚:
二阶段-提交:
既然说到了undolog,seata中是如何记录的呢?
UNDO_LOG Table
,MySQL示例如下:
DROP TABLE IF EXISTS `undo_log`;
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
一般的事务操作有插入、更新、删除几种,下面分别看下个各情况的执行流程:
注意:回滚数据时,会对比当前数据和undolog是否一致,如果不一致表示有其他事务进行了数据更新操作,此时时不能直接进行回滚数据的。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有