13.Spring Cloud Alibaba Seata分布式事务使用入门(二)

本文纠正了上篇关于Seata分布式事务的误解,强调了阅读官方文档的重要性。详细探讨了Seata AT模式,包括模拟事务成功和失败的情况,分析了日志和回滚过程。此外,提到了写隔离和读隔离的概念,并指出在特定场景下如何调整。最后,提及Seata XA模式,并建议参考GitHub上的TCC和Saga模式示例。
摘要由CSDN通过智能技术生成
更正问题

上篇博客Spring Cloud Alibaba Seata分布式事务使用入门介绍了事务的ACID特性,分布式CAP原则,以及分布式事务常见解决方案。这篇博客做一些在使用阿里的开源分布式组件Seata的一些补充。

本着实事求是的态度,今天上午又巴拉巴拉的翻阅了Seata官网的博客,查看了别人使用nacos作为seata服务端的配置中心,导入的nacos中的结果跟我上篇博客中的一致。这里更正上篇博客中自己误认为nacos导入脚本存在问题导致导入配置错误。

在Seata官网的博客中,也找到了关于file.conf文件中配置为db模式(file模式适合单机,db模式适合集群)的建表语句:

CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(96),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

因为Seata本身的更新也比较快,每个人使用版本不一致,文档不一致,建议先阅读官方文档,博客,并查看版本更新日志,自己动手,有问题再解决呗。

本篇博客用来对Seata做一点小小的补充

Seata AT 模式

AT模式案例直接去官网中查阅即可,建表语句,业务核心伪代码都在,自己搭建TC,TM,RM。

这里重新模拟成功,失败的测试用例,查看全方面的日志,进行分析。

模拟成功
  • TC 日志

    在这里插入图片描述

  • TM 日志

    Business-Service 控制台

    在这里插入图片描述

  • RM 日志

    • Storage-Service控制台

      在这里插入图片描述

    • Account-Service控制台

      在这里插入图片描述

    • Order-Service控制台

      在这里插入图片描述

通过上面的日志结合一起来分析:

  1. 调用Business-Service中的purchase方法,向TC开启全局事务,并生成全局的xid:ip:port:79972829746958336
  2. Storage-Service,进行更新操作(业务),注册分支(branchId = 79972830313189376),并在对应数据库的undo_log中插入数据,这个数据用于更新操作的回滚。最后向TC通知操作结果。
  3. Account-Service,更新数据(业务),注册分支(branchId = 79972831156244480),undo_log表插入数据,通知TC操作结果
  4. Order-Service,插入数据(业务),注册分支(branchId = 79972831894441984),ndo_log表插入数据,通知TC操作结果
  5. Business-Service执行成功,通知TC全局提交
  6. TC通知所有RM提交成功,RM会删除掉undo_log表中的数据。
模拟失败

在模拟中发现,成功或失败,undo_log表中的数据被清理的很快,我暂时没有抓取到undo_log表中的数据。

  • TC 日志

    在这里插入图片描述

  • TM 日志

    Business-Service 控制台

    在这里插入图片描述

  • RM 日志

    • Storage-Service控制台

      在这里插入图片描述

    • Account-Service控制台

      在这里插入图片描述

    • Order-Service控制台

      在这里插入图片描述

通过日志分析,在Account-Service中我手动抛出了异常,Storage-Service中的更新操作,通过undo_log表中的日志数据,进行了回滚。

通过对undo_log表字段分析:

在这里插入图片描述

xid,branch_id通过日志都看到了。

通过字段类型来看,这里面应该是记录回滚前后的详细数据信息。

好在官网给了一张

在这里插入图片描述

官方给的详细的流程是:

  1. RM收到TC的分支回滚请求后,开启一个本地事务
  2. 通过xid和branch id查找undo_log表中的记录
  3. 数据校验
  4. 根据undo_log表中的信息生成回滚SQL并执行
  5. 提交本地事务,并把回滚的结果反馈给TC
写隔离

AT模式下,在一阶段本地事务提交前,必须要拿到全局锁。如果拿不到,则不能提交本地的事务。在不停尝试拿全局锁时,超出了一定范围,则放弃拿全局锁,回滚本地事务,并释放本地锁。

读隔离

在数据库本地事务隔离级别为读已提交(或以上基础上),Seata AT模式默认全局隔离是读未提交。

如果在特定场景下,必须要求全局的读已提交,则通过SELECT ... FRO UPDATE语句代理。

关于写隔离、读隔离。请阅读官网结合的例子理解。Seata AT模式

Seata XA模式

关于XA模式,与AT模式不同的是在RM中以XA协议的机制来管理分支事务。

在AT模式的代码中改动不是特别多,只需要在数据源配置的类中修改一下返回数据源的具体实现类。

在这里插入图片描述

这里说一下重点,因为是自己配置数据源,我们需要将自动配置的类给移除掉(不然启动会报错)。

在这里插入图片描述

在启动类的@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

Seata TCC模式,Seata Saga模式,我这里直接去GitHub上面拉取的例子运行的。

直接去拉取例子,结合文档吧。比我这讲的老详细了。0.0

Seata tcc 模块源码分析

seata-samples

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值