05-AT模式
AT模式同样是分阶段提交事务的模型,不过弥补了XA模式锁定资源周期长的问题。
1.seata的AT的模型
基本流程图:

阶段一RM的工作:
注册分支事务;

其中一个分支业务要执行业务sql:
update tb_account set money = money - 10 where id = 1
AT模式下,当前分支事务执行流程如下:
一阶段:
1)RM发起并注册全局事务到TC
2)RM调佣分支事务
3)分支事务准备执行业务SQL
4)RM拦截拦截业务SQL,根绝where条件,形成快照。
{
"user202103032042012": 1, "money": 100
}
5)RM执行业务SQL,提交本地事务,并释放数据库锁,此时,money=90
6)RM报告事务状态给TC
二阶段:
1)TM通知TC事务结束
2)TC检查事务状态:
a)如果都成功,则立即删除快照。
b)如果有分支事务失败,则需要回滚,根据快照恢复数据。
流程图:

3.XA和AT的区别
1)XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
2)XA模式依赖数据库机制实现回滚;AT模式使用数据快照实现回滚。
3)XA是强一致,AT是最终一致。
4.脏写问题
在多线程并发访问AT模式的分布式事务,会出现脏写问题,如图:

解决思路是引入全局锁。在释放DB锁之前拿到分布式锁。避免同一时刻有另一个事务操作当前数据。

5.优缺点
AT模式优点:
1)一阶段完成直接事务提交,释放数据库资源,性能比较好。
2)利用全局锁实现读写隔离
3)没有代码进入,代码自动完成回滚和提交。
AT模式缺点:
1)两阶段之间属于软状态,是最终一致。
2)框架的快照功能会影响性能,但是比XA模式好很多。
6.实现AT模式
1)AT模式快照生成和回滚动作都是由框架实现,没有任何代码侵入,因此实现非常简单。只不过,AT模式需要一个表记录全局锁,另一张表记录数据快照undo-log。
lock_table导入到TC服务关联的数据库:
DROP TABLE IF EXISTS `lock_table`; CREATE TABLE `lock_table` ( `row_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `xid` varchar(96) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `transaction_id` bigint(20) NULL DEFAULT NULL, `branch_id` bigint(20) NOT NULL, `resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `table_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `pk` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `gmt_create` datetime NULL DEFAULT NULL, `gmt_modified` datetime NULL DEFAULT NULL, PRIMARY KEY (`row_key`) USING BTREE, INDEX `idx_branch_id`(`branch_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; SET FOREIGN_KEY_CHECKS = 1;
undo_log表导入到微服务关联的数据库:
DROP TABLE IF EXISTS `undo_log`; CREATE TABLE `undo_log` ( `branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id', `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'global transaction id', `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'undo_log context,such as serialization', `rollback_info` longblob NOT NULL COMMENT 'rollback info', `log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status', `log_created` datetime(6) NOT NULL COMMENT 'create datetime', `log_modified` datetime(6) NOT NULL COMMENT 'modify datetime', UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Compact;
2)修改application.yml文件将事务模式改为AT模式即可
seata:
registry:
type: nacos
nacos:
server-addr: 192.168.136.160:8848
namespace: ""
group: DEFAULT_GROUP
application: seata-server
username: nacos
password: nacos
tx-service-group: seata-demo #事务组名称
service:
vgroup-mapping: # 事务组与cluster的映射关系
seata-demo: GZ
data-source-proxy-mode: AT

浙公网安备 33010602011771号