SpringCloud-Seata
- 软件开发
- 2025-08-30 08:24:01

Seata分布式事务
Seata(Simple Extensible Autonomous Transaction Architecture)是一个开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将分布式事务拆分为全局事务和分支事务,通过 TC(Transaction Coordinator)、TM(Transaction Manager)和 RM(Resource Manager)三个组件的协作,实现了分布式事务的 ACID 特性。
官网地址:Apache Seata seata.apache.org/?spm=5176.29160081.0.0.74805c72agUsGU
Seata 的核心组件TC (Transaction Coordinator): 事务协调者,维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager): 事务管理器,定义全局事务的边界,申请开启、提交或回滚全局事务。
RM (Resource Manager): 资源管理器,管理分支事务处理的资源,与 TC 通讯以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
简而言之:如果将分布式事务整体看作为一个糖葫芦串的话。TC (Transaction Coordinator)就可以看作是Seata本身,即是串糖葫芦的竹签。TM (Transaction Manager)就是触发分布式事务的第一个事务,即第一个糖葫芦。RM (Resource Manager)就是mysql数据库本身。
Seata 的事务模式Seata 提供了 AT、TCC、SAGA 和 XA 四种事务模式,以适应不同的业务场景和需求。
AT 模式(Automatic Transaction):基于支持本地 ACID 事务的关系型数据库,通过代理数据源的方式,拦截 SQL 操作,自动补偿回滚,实现分布式事务。
TCC 模式(Try-Confirm-Cancel):应用层侵入业务代码,通过定义 Try、Confirm 和 Cancel 三个操作,由框架调用以完成分支事务的提交或回滚。
SAGA 模式:通过事件驱动的方式,补偿服务在接收到事件后进行相应的业务处理,实现长事务的最终一致性。
XA 模式:基于 XA 协议的两阶段提交,通过数据库支持的 XA 事务来实现分布式事务。
Seata 的基本工作流程全局事务的开始:事务管理器。当业务应用需要执行一个全局事务时,TM 会向 TC(Transaction Coordinator)申请开启一个新的全局事务。TC 会生成一个全局唯一的事务 ID(XID),并返回给 TM。
分支事务的注册:资源管理器。在全局事务的上下文中,每个需要参与该事务的服务(或数据库)都会作为一个分支事务。RM 在执行分支事务之前,会向 TC 注册该分支事务,并报告其初始状态。
分支事务的执行:在注册分支事务后,RM 会开始执行实际的业务操作(如数据库操作)。这些操作会被 RM 拦截并记录下来,以便在需要时进行回滚。
一,二阶段提交/回滚:跟据具体情况进行提交或者回滚策略
全局事务结束:无论全局事务是提交还是回滚,当所有分支事务都处理完毕后,TM 会结束该全局事务的生命周期。
操作流程:
sql语句地址: github /seata/saeta/blob/develop/script/server/db/masql.sql github /seata/saeta/blob/develop/script/server/db/masql.sql
==============================数据库语句准备======================================= CREATE DATABASE seata; USE seata; -- ------------------- 当storeMode为'db'时使用的脚本-------------------------------- -- 存储GlobalSession数据的表 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_status_gmt_modified` (`status` , `gmt_modified`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- 存储BranchSession数据的表 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 = utf8mb4; -- 存储锁数据的表 CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(128), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking', `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_status` (`status`), KEY `idx_branch_id` (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; CREATE TABLE IF NOT EXISTS `distributed_lock` ( `lock_key` CHAR(20) NOT NULL, `lock_value` VARCHAR(20) NOT NULL, `expire` BIGINT, primary key (`lock_key`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0); INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0); INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0); INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0); ==========================业务数据库创建(日志表+业务表)============================= -- 对于AT模式,您必须为您的业务数据库初始化此SQL。Seata服务器不需要它。(日志表) CREATE TABLE IF NOT EXISTS `undo_log` ( `branch_id` BIGINT NOT NULL COMMENT 'branch transaction id', `xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id', `context` VARCHAR(128) 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 KEY `ux_undo_log` (`xid`, `branch_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table'; ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`); -- 业务表,下面列举一个例子订单表,跟据自己的业务创建 CREATE TABLE t_order( `id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id', `product_id` BIGINT(11)DEFAULT NULL COMMENT '产品id', `count` INT(11) DEFAULT NULL COMMENT '数量', `money` DECIMAL(11,0) DEFAULT NULL COMMENT '金额', `status` INT(1) DEFAULT NULL COMMENT '订单状态: 0:创建中; 1:已完结' )ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; SELECT * FROM t_order; ======================添加依赖=================================== <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency> ======================配置文件====================================== seata: application-id: ${spring.application.name} tx-service-group: ${spring.application.name}-group service: vgroup-mapping: ${spring.application.name}-group: default grouplist: default: 127.0.0.1:8091 @Override //在触发全局事务的方法上进行标注即可,就可以达到分布式事务异常回滚的效果 @GlobalTransactional(name = "zzyy-create-order",rollbackFor = Exception.class) //AT public void create(Order order) { //相关业务逻辑实现 }SpringCloud-Seata由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“SpringCloud-Seata”
上一篇
读书笔记-修改代码的艺术