目录
建seata_order库+建t_order表+undo_log表
建seata_storage库+建t_storage 表+undo_log表
建seata_account库+建t_account 表+undo_log表
2.修改公共cloud-api-commons新增库存和账户两个Feign服务接口
SpringBootApplication是一个组合注解,主要用于标记Spring Boot的主配置类,用于启动Spring Boot应用程序。它由以下三个注解组成:
2).此时我们没有在订单模块添加@GlobalTransactional
2.超时异常出错,没有@GlobalTransactional
3.超时异常解决,添加@GlobalTransactional
一、分布式事务面试题
1.多个数据库之间如何处理分布式事务?2.若拿出如下场景,阁下将如何应对?3.阿里巴巴的Seata-AT模式如何做到对业务的无侵入?4.对于分布式事务问题,你知道的解决方案有哪些?请你谈谈?
1.多个数据库之间如何处理分布式事务?

2.若拿出如下场景,阁下将如何应对?

冻结库存 是指在ERP系统中, 将部分库存暂时锁定,使其不能参与正常的出库和入库操作 。这种操作通常用于防止库存被意外或错误地使用,确保在特定时间段内库存的稳定性和可用性。冻结库存的方法包括设置库存冻结、使用库存锁定功能、创建保留订单和利用批次管理。
3.阿里巴巴的Seata-AT模式如何做到对业务的无侵入?
4.对于分布式事务问题,你知道的解决方案有哪些?请你谈谈?
- TCC(Try-Confirm-Cancel)又被称补偿事务
- 类似2PC的柔性分布式解决方案,2PC改良版
二、分布式事务问题如何产生?请先看业务
一次业务操作需要 跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。但是关系型数据库提供的能力是基于 单机事务的,一旦遇到分布式事务场景,就需要通过更多其他技术手段来解决问题。
分布式事务之前:
- 单机单库没这个问题
- 表结构的关系从1:1->1:N -> N:N
分布式事务改变后:

三、Seata简介
Seata的发展历程:
阿里巴巴作为国内最早一批进行应用分布式(微服务化)改造的企业,很早就遇到微服务架构下的分布式事务问题。2019年1月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案:2014 年,阿里中间件团队发布 TXC(Taobao Transaction Constructor),为集团内应用提供分布式事务服务。2016 年,TXC 在经过产品化改造后,以 GTS(Global Transaction Service) 的身份登陆阿里云,成为当时业界唯一一款云上分布式事务产品。在阿云里的公有云、专有云解决方案中,开始服务于众多外部客户。2019 年起,基于 TXC 和 GTS 的技术积累,阿里中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一起建设这个分布式事务解决方案。2019 年 fescar(全称fast easy commit and rollback) 被重命名为了seata(simple extensiable autonomous transaction architecture)。TXC、GTS、Fescar 以及 seata 一脉相承,为解决微服务架构下的分布式事务问题交出了一份与众不同的答卷。Seata最初是阿里巴巴开发的,但现在已经捐赠给了Apache基金会,成为Apache项目的一部分。
- 单个数据库只能对本身进行事务的控制, 而seata是分布式事务框架,可以对多个数据库进行全局的事务控制,保证全局事务的运行正常的框架。
- 当事物发生超时或异常时,seata会对所管理数据库,统一进行数据回滚,保证数据的正确性。
官网及源码
使用
Seata的分布式交易解决方案

四、Seata工作流程简介:
分布式事务的理解:
- 分布式事务是由一批分支事务组成的全局事务,通常分支事务只是本地事务。
- 纵观整个分布式事务的管理,就是全局事务ID的传递和变更,要让开发者无感知。
Seata对分布式事务的协调和控制就是1+3
1+3:1个XID+TC+TM+RM
- 1个XID :XID是全局事务的唯一标识,它可以在服务的调用链路中传递,绑定到服务的事务上下文中。
- TC (Transaction Coordinator) - 事务协调者
- TM (Transaction Manager) - 事务管理器
- RM (Resource Manager) - 资源管理器
- TC(Transaction Coordinator)事务协调器:就是Seata,负责维护全局事务和分支事务的状态,驱动全局事务提交或回滚。
- TM(Transaction Manager) 事务管理器:标注全局@GlobalTransactional启动入口动作的微服务模块(比如订单模块),它是事务的发起者,负责定义全局事务的范围,并根据TC维护的全局事务和分支事务状态,做出开始事务、提交事务、回滚事务的决议。
- RM(Resource Manager)资源管理器:就是mysql数据库本身,可以是多个RM,负责管理分支事务上的资源,像TC注册分支事务,汇报分支事务状态,驱动分支事务的提交和回滚。

分布式事务的执行流程-总结:(重点)

@GlobalTransactional
public void doBusiness() {
// 本地事务
serviceA.doSomething();
// 本地事务
serviceB.doSomethingElse();
}
@GlobalTransactional
public void globalMethod() {
// 调用另一个标记为@GlobalTransactional的方法
nestedMethod();
// 业务逻辑...
}
@GlobalTransactional
public void nestedMethod() {
// 业务逻辑...
}
五、各事务模式(重点)
- Seata AT 模式
- Seata TCC 模式
- Seata Saga 模式
- Seata XA 模式
Seata AT 模式(常用)
AT 模式是 Seata 创新的一种非侵入式的分布式事务解决方案,Seata 在内部做了对数据库操作的代理层,我们使用 Seata AT 模式时,实际上用的是 Seata 自带的数据源代理 DataSourceProxy,Seata 在这层代理中加入了很多逻辑,比如插入回滚 undo_log 日志,检查全局锁等。
适用场景:
- 适用场景:主要用于CRUD(创建、读取、更新、删除)操作较多的业务场景,尤其是当业务逻辑直接操作数据库,并且可以容忍短暂的数据不一致时。AT模式通过记录数据的前后镜像来实现撤销(回滚)操作,适合于大部分单纯依赖于单个数据库事务的微服务场景。
- 优点:简单易用,不需要改动业务代码,自动完成分布式事务的提交和回滚。
- 缺点:不适合跨多种存储资源的事务,且在高并发场景下性能可能受影响。
前提
- 基于支持本地 ACID 事务的关系型数据库。
- Java 应用,通过 JDBC 访问数据库。
整体机制
- 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
- 二阶段:
- 提交异步化,非常快速地完成。
- 回滚通过一阶段的回滚日志进行反向补偿。
整体机制的理解
一阶段过程;
1 解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,2 执行“业务 SQL”更新业务数据,在业务数据更新之后,3 其保存成“after image”,最后生成行锁。

二阶段异常回滚:
二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用undo_log中的“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据, 如果不一致就说明有脏写,出现脏写就需要转人工处理。

二阶段正常提交:
因为“业务 SQL”在一阶段已经提交至数据库,所以Seata框架只需将 一阶段保存的快照数据和行锁删掉,完成数据清理即可。

写隔离
- 一阶段本地事务提交前,需要确保先拿到 全局锁 。
- 拿不到 全局锁 ,不能提交本地事务。
- 拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。
以一个示例来说明:


读隔离

工作机制示例:
Field |
Type |
Key |
id
|
bigint(20)
|
PRI
|
name
|
varchar(100)
|
|
since
|
varchar(100)
|
update product set name = 'GTS' where name = 'TXC';
一阶段
- 解析 SQL:得到 SQL 的类型(UPDATE),表(product),条件(where name = 'TXC')等相关的信息。
- 查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。
select id, name, since from product where name = 'TXC';
id
|
name
|
since
|
1
|
TXC
|
2014
|
3.执行业务 SQL:更新这条记录的 name 为 'GTS'。
4.查询后镜像:根据前镜像的结果,通过 主键 定位数据。
select id, name, since from product where id = 1;
id
|
name
|
since
|
1
|
GTS
|
2014
|
5.插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。
{
"branchId": 641789253,
"undoItems": [{
"afterImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}, {
"name": "name",
"type": 12,
"value": "GTS"
}, {
"name": "since",
"type": 12,
"value": "2014"
}]
}],
"tableName": "product"
},
"beforeImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}, {
"name": "name",
"type": 12,
"value": "TXC"
}, {
"name": "since",
"type": 12,
"value": "2014"
}]
}],
"tableName": "product"
},
"sqlType": "UPDATE"
}],
"xid": "xid:xxx"
}
6.提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局锁 。
7.本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。
8.将本地事务提交的结果上报给 TC。
二阶段-回滚
1.收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。
2.通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。
3.数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。
4.根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句:
update product set name = 'TXC' where id = 1;
5.提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。
二阶段-提交
- 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
- 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。
回滚日志表
Field
|
Type
|
branch_id
|
bigint PK
|
xid
|
varchar(100)
|
context
|
varchar(128)
|
rollback_info
|
longblob
|
log_status
|
tinyint
|
log_created
|
datetime
|
log_modified
|
datetime
|
-- 注意此处0.7.0+ 增加字段 context
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;
Seata TCC 模式
TCC 模式是 Seata 支持的一种由业务方细粒度控制的侵入式分布式事务解决方案,是继 AT 模式后第二种支持的事务模式,最早由蚂蚁金服贡献。其分布式事务模型直接作用于服务层,不依赖底层数据库,可以灵活选择业务资源的锁定粒度,减少资源锁持有时间,可扩展性好,可以说是为独立部署的 SOA 服务而设计的。
适用场景:
- 适用场景:适用于需要显式控制事务边界的复杂业务流程,特别是在业务操作可以明确分为尝试(Try)、确认(Confirm)和取消(Cancel)三个阶段的情况下。TCC模式适合于执行时间较长,需要人工干预或第三方服务参与的分布式事务。
- 优点:灵活性高,可以精细控制事务的每个阶段,适用于复杂的业务逻辑。
- 缺点:需要用户显式地实现Try、Confirm、Cancel三个操作,增加了开发的复杂度。
Seata Saga 模式
Saga 模式是 SEATA 提供的长事务解决方案,在 Saga 模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
适用场景:
- 适用场景:适用于长事务场景,其中业务流程包含一系列的本地事务,这些本地事务需要按照一定的顺序执行。SAGA模式通过定义一系列的事务步骤和相对应的补偿操作(回滚操作)来管理事务,适合于微服务架构下的复杂业务流程。
- 优点:适合长事务处理,可以保证分布式事务的最终一致性。
- 缺点:需要定义每个步骤的补偿操作,对业务侵入性较高。
Seata XA 模式
XA 模式是从 1.2 版本支持的事务模式。XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准。Seata XA 模式是利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种事务模式。
适用场景:
- 适用场景:适用于长事务场景,其中业务流程包含一系列的本地事务,这些本地事务需要按照一定的顺序执行。SAGA模式通过定义一系列的事务步骤和相对应的补偿操作(回滚操作)来管理事务,适合于微服务架构下的复杂业务流程。
- 优点:适合长事务处理,可以保证分布式事务的最终一致性。
- 缺点:需要定义每个步骤的补偿操作,对业务侵入性较高。
六、Seata-Server2.0.0安装
1.下载地址2.下载版本3.各种seata参数官网参考4.Seata新手部署指南5.mysql8.0数据库里面建库+建表6.更改配置7.先启动Nacos2.2.3端口号88488.再启动seata-server-2.0.0
1.下载地址
2.下载版本

3.各种seata参数官网参考
关注属性(详细描述见全属性)
server 端
|
client 端
|
registry.type
|
registry.type
|
config.type
|
config.type
|
#store.mode=db 需要以下配置
|
service.vgroupMapping.my_test_tx_group
|
store.db.driverClassName
|
service.default.grouplist
|
store.db.url
|
service.disableGlobalTransaction
|
store.db.user
|
|
store.db.password
|
|
#store.mode=redis 需要以下配置
|
|
store.redis.host
|
|
store.redis.port
|
|
store.redis.database
|
|
store.redis.password
|
|
#store.mode=raft 需要以下配置
|
|
server.raft.group
|
|
server.raft.server-addr
|
|
server.raft.snapshot-interval
|
全属性
公共部分
key
|
desc
|
remark
|
change record
|
transport.type
|
socket 通信方式
|
TCP、UNIX_DOMAIN_SOCKET,默认 TCP
|
|
transport.server
|
socket 通道类型
|
NIO、NATIVE(根据操作系统类型和 socket 通信方式选择 KQueue 或 Epoll,注意 Windows 只支持 NIO,选择这种方式会抛出异常)
|
|
transport.threadFactory.bossThreadSize
|
Netty 通信模型 Boss group 线程数
|
默认 1
|
|
transport.threadFactory.workerThreadSize
|
Netty 通信模型 Worker group 线程数
|
可配置线程数或选择特定线程工作模式下的线程数,线程的默认工作模式有 4 种:Auto(2*CPU 核数 + 1)、Pin(CPU 核数,适用于计算密集型任务)、BusyPin(CPU 核数 + 1,适用于计算密集型且内存比较有限的场景)、Default(2*CPU 核数,适用于 IO 密集型任务),默认值为 Default 模式
|
|
transport.shutdown.wait
|
服务端 Netty 线程池关闭前等待服务下线时间
|
默认 3 秒
|
|
transport.serialization
|
client 和 server 通信编解码方式
|
seata(ByteBuf)、protobuf、kryo、hessian、fst,默认 seata
|
|
transport.compressor
|
client 和 server 通信数据压缩方式
|
none、gzip、zip、sevenz、bzip2、lz4、deflater、zstd,默认 none
|
1.2.0 之前:gzip
1.2.0:zip、sevenz、bzip2
1.3.0:lz4
1.4.1:deflater
1.5.1:zstd
|
transport.heartbeat
|
client 和 server 通信心跳检测开关
| <