每个微服务都调用不同的数据库,服务内部的事务由本地事务所保证,全局事务的一致性问题就没法保证。一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。
@Transaction为本地事务,@GlobalTransaction为全局事务
——概念
ID+三组件模型
- Transaction ID XID:全局事务的唯一ID
- Transaction Coordinator(TC):事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚;
- Transaction Manager(TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议;
- Resource Manager(RM):控制分支事务,负责分支注册,状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚;
分布式事务的执行流程
- TM开启分布式事务(TM向TC注册全局事务记录)
- 换业务场景,编排数据库,服务等事务内资源(RM向TC汇报准备状态)
- TM结束分布式事务,事务一阶段结束(TM通知TC提交 、回滚分布式事务)
- TC汇总事务信息,决定分布式事务是提交还是回滚
- TC通知所有RM提交、回滚,事务二阶段结束
AT模式的业务无侵入
- 一阶段
- 二阶段提交
- 二阶段回滚
——下载安装
- 下载地址:http://seata.io/zh-cn/blog/download.html,选择合适的版本binary
- 修改conf / file.conf文件:
- 备份
- 自定义事务组名称:
vgroup_mapping.my_test_tx_group = "test_tx_group"
- 事务日志存储模式为db:
mode = "db"
- 数据库连接信息:
url = "jdbc:mysql://127.0.0.1:3306/seata" user = "root" password = "123456"
- 在mysql建seata库
- 在seata库里建表:
-- the table to store GlobalSession data
drop table if exists `global_table`;
create table `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`)
);-- the table to store BranchSession data
drop table if exists `branch_table`;
create table `branch_table` (`branch_id` bigint not null,`xid` varchar(128) not null,`transaction_id` bigint ,`resource_group_id` varchar(32),`resource_id` varchar(256) ,`lock_key` varchar(128) ,`branch_type` varchar(8) ,`status` tinyint,`client_id` varchar(64),`application_data` varchar(2000),`gmt_create` datetime,`gmt_modified` datetime,primary key (`branch_id`),key `idx_xid` (`xid`)
);-- the table to store lock data
drop table if exists `lock_table`;
create table `lock_table` (`row_key` varchar(128) not null,`xid` varchar(96),`transaction_id` long ,`branch_id` long,`resource_id` varchar(256) ,`table_name` varchar(32) ,`pk` varchar(36) ,`gmt_create` datetime ,`gmt_modified` datetime,primary key(`row_key`)
);
- 修改conf / registry.conf配置文件
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "nacos"nacos {
serverAddr = "localhost:8848"namespace = ""cluster = "default"}
- 启动nacos
- 再启动seata