分布式事务Seata

本文最后更新于:2025年5月20日 下午

Seata

官网地址:https://seata.apache.org/zh-cn/

下载Seata服务器

需下载与springcloud项目内对应的版本

例如:

spring-cloud-alibaba2021.0.5.0 对应的就是Seata v1.6.1

这样服务器就下载1.6.1.zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.5.0</version>
<packaging>pom</packaging>
...
<properties>
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
<sentinel.version>1.8.6</sentinel.version>
<maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<flatten-maven-plugin.version>1.2.7</flatten-maven-plugin.version>
<revision>2021.0.5.0</revision>
<nacos.client.version>2.2.0</nacos.client.version>
<seata.version>1.6.1</seata.version>
<spring.context.support.version>1.0.11</spring.context.support.version>
</properties>

版本历史https://seata.apache.org/zh-cn/release-history/seata-server

Seata 2.x

发布日期 版本号 二进制下载 docker 镜像 checksum 发布说明 参考文档 是否 ASF 版本
2023-11-24 2.0.0 2.0.0.zip seataio/seata-server:2.0.0 5c5c6a98649f37ed7894743b21bc8777 2.0.x 发布说明 2.0.x 快速开始

Seata 1.x

发布日期 版本号 二进制下载 docker 镜像 checksum 发布说明 参考文档 是否 ASF 版本
2023-10-31 1.8.0 1.8.0.zip seataio/seata-server:1.8.0 f5de162a4577f5f96828cba75d912240 1.8.x 发布说明 1.8.x 快速开始
2023-09-05 1.7.1 1.7.1.zip seataio/seata-server:1.7.1 5e7f41965f8f26a46b727d204eef3054 1.7.x 发布说明 1.7.x 快速开始
2023-07-11 1.7.0 1.7.0.zip seataio/seata-server:1.7.0 ca1f7444f19db7245df1e460fd468d30 1.7.x 发布说明 1.7.x 快速开始
2022-12-22 1.6.1 1.6.1.zip seataio/seata-server:1.6.1 736ded86ab3adca52e95d253889179ef 1.6.x 发布说明 1.6.x 快速开始
2022-12-17 1.6.0 1.6.0.zip seataio/seata-server:1.6.0 cacf323b8653c549fef806049f9e01f2 1.6.x 发布说明 1.6.x 快速开始
2022-07-13 1.5.2 1.5.2.zip seataio/seata-server:1.5.2 41dbc4e3519a71d92afc212bb71a41c4 1.5.x 发布说明 1.5.x 快速开始
2022-05-17 1.5.1 1.5.1.zip seataio/seata-server:1.5.1 3f75a4dc7bf553849dd439cc0faa2fdc 1.5.x 发布说明 1.5.x 快速开始
2021-04-25 1.4.2 1.4.2.zip seataio/seata-server:1.4.2 4fb356c3c08e0bbebe2af66419f62f2d 1.4.x 发布说明 1.4.x 快速开始
2021-02-08 1.4.1 1.4.1.zip seataio/seata-server:1.4.1 fd5f05b3d2894e6f6cb6ab7ab21c5207 1.4.x 发布说明 1.4.x 快速开始
2020-11-02 1.4.0 1.4.0.zip seataio/seata-server:1.4.0 5a8304aee9ba2bdf80a7f96cb2328f69 1.4.x 发布说明 1.4.x 快速开始
2020-07-16 1.3.0 1.3.0.zip seataio/seata-server:1.3.0 d888a04eb35f1de7cd7e89efabbbe779 1.3.x 发布说明 1.3.x 快速开始
2020-04-21 1.2.0 1.2.0.zip seataio/seata-server:1.2.0 420ccff3f69377ee2114c9a390a5e0e3 1.2.x 发布说明 1.2.x 快速开始
2020-02-20 1.1.0 1.1.0.zip seataio/seata-server:1.1.0 1653d4af05bccf48c8417a829c9ca0cf 1.1.x 发布说明 1.1.x 快速开始
2019-12-21 1.0.0 1.0.0.zip seataio/seata-server:1.0.0 c889eab52fc658cd1c4a293858ded87f 1.0.x 发布说明 1.0.x 快速开始

配置Seata

配置数据库

sql文件

1
2
# sql文件地址 (dm、mysql、oracle、postgresql)
https://github.com/apache/incubator-seata/tree/master/script/server/db

配置yml

路径:seata\conf\application.yml

配置示例(根据需要修改):

注:建议自己学习的话,先用默认类型file,之后再尝试将注册中心改成nacos等,这样修改后,就必须先启动nacos后,才能再启动seata了,以nacos作为注册中心可以方便集中管理配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#  Copyright 1999-2019 Seata.io Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

server:
port: 7091

spring:
application:
name: seata-server

logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash

seata:
config:
# support: nacos 、 consul 、 apollo 、 zk 、 etcd3
type: file
nacos:
server-addr: 127.0.0.1:8848
namespace:
group: SEATA_GROUP
username:
password:
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
data-id: seataServer.properties
consul:
server-addr: 127.0.0.1:8500
acl-token:
key: seata.properties
apollo:
appId: seata-server
apollo-meta: http://192.168.1.204:8801
apollo-config-service: http://192.168.1.204:8080
namespace: application
apollo-access-key-secret:
cluster: seata
zk:
server-addr: 127.0.0.1:2181
session-timeout: 6000
connect-timeout: 2000
username:
password:
node-path: /seata/seata.properties
etcd3:
server-addr: http://localhost:2379
key: seata.properties
registry:
# support: nacos 、 eureka 、 redis 、 zk 、 consul 、 etcd3 、 sofa
type: file
preferred-networks: 30.240.*
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
cluster: default
username:
password:
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
eureka:
service-url: http://localhost:8761/eureka
application: default
weight: 1
redis:
server-addr: localhost:6379
db: 0
password:
cluster: default
timeout: 0
zk:
cluster: default
server-addr: 127.0.0.1:2181
session-timeout: 6000
connect-timeout: 2000
username:
password:
consul:
cluster: default
server-addr: 127.0.0.1:8500
acl-token:
etcd3:
cluster: default
server-addr: http://localhost:2379
sofa:
server-addr: 127.0.0.1:9603
application: default
region: DEFAULT_ZONE
datacenter: DefaultDataCenter
cluster: default
group: SEATA_GROUP
address-wait-time: 3000

server:
service-port: 8091 #If not configured, the default is '${server.port} + 1000'
max-commit-retry-timeout: -1
max-rollback-retry-timeout: -1
rollback-retry-timeout-unlock-enable: false
enable-check-auth: true
enable-parallel-request-handle: true
retry-dead-threshold: 130000
xaer-nota-retry-timeout: 60000
enableParallelRequestHandle: true
recovery:
committing-retry-period: 1000
async-committing-retry-period: 1000
rollbacking-retry-period: 1000
timeout-retry-period: 1000
undo:
log-save-days: 7
log-delete-period: 86400000
session:
branch-async-queue-size: 5000 #branch async remove queue size
enable-branch-async-remove: false #enable to asynchronous remove branchSession
store:
# support: file 、 db 、 redis
mode: file
session:
mode: file
lock:
mode: file
file:
dir: sessionStore
max-branch-session-size: 16384
max-global-session-size: 512
file-write-buffer-cache-size: 16384
session-reload-read-size: 100
flush-disk-mode: async
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
user: mysql
password: mysql
min-conn: 10
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 1000
max-wait: 5000
redis:
mode: single
database: 0
min-conn: 10
max-conn: 100
password:
max-total: 100
query-limit: 1000
single:
host: 127.0.0.1
port: 6379
sentinel:
master-name:
sentinel-hosts:
metrics:
enabled: false
registry-type: compact
exporter-list: prometheus
exporter-prometheus-port: 9898
transport:
rpc-tc-request-timeout: 15000
enable-tc-server-batch-send-response: false
shutdown:
wait: 3
thread-factory:
boss-thread-prefix: NettyBoss
worker-thread-prefix: NettyServerNIOWorker
boss-thread-size: 1

微服务集成Seata

引入依赖

对应的服务都需要引入此依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--统一配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--读取bootstrap文件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

修改配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
seata:
registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
type: nacos # 注册中心类型 nacos
nacos:
server-addr: 127.0.0.1:8848 # nacos地址
namespace: "" # namespace,默认为空
group: SEATA_GROUP # 分组,需与seata配置文件中的分组一致
application: seata-server # seata服务名称
username:
password:
tx-service-group: hmall # 事务组名称
service:
vgroup-mapping: # 事务组与tc集群的映射关系
hmall: "default"
grouplist:
default: 127.0.0.1:8091 # tc集群地址
default2: 127.0.0.1:8091
disable-global-transaction: false # 是否禁用全局事务
enable-degrade: false # 是否开启降级
data-source-proxy-mode: AT # 事务代理模式 AT模式[最终一致] XA[强一致]

还有一种方法是在resource文件夹下创建file.conf

通常只配置service内的选项即可,其他默认。这种方式好像是1.0版本以前的配置方法,只不过现在也兼容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
transport {
# Seata 传输层配置
type: "TCP" # 传输类型,默认 TCP
server: "NIO" # 服务端类型,默认 NIO
heartbeat: true # 是否开启心跳检测
serialization: "seata" # 序列化方式,默认 "seata"
compressor: "none" # 压缩方式,默认 "none"
}

service {
# 事务组映射配置
vgroupMapping.default_tx_group: "default" # 默认事务组映射
# Seata 服务器地址列表
default.grouplist: "127.0.0.1:8091"
# 是否开启降级处理
enableDegrade: false
# 是否禁用全局事务
disableGlobalTransaction: false
}

client {
# 客户端配置
rm {
asyncCommitBufferLimit: 10000 # 异步提交缓存限制
reportRetryCount: 5 # 报告重试次数
tableMetaCheckEnable: false # 是否开启表元数据检查
reportSuccessEnable: false # 是否报告成功
}
tm {
commitRetryCount: 5 # 提交重试次数
rollbackRetryCount: 5 # 回滚重试次数
}
undo {
dataValidation: true # 是否开启数据验证
logSerialization: "jackson" # Undo 日志序列化方式
logTable: "undo_log" # Undo 日志表名
}
loadBalance {
type: "Random" # 负载均衡策略,默认随机
virtualNodes: 10 # 虚拟节点数
}
}

store {
# 数据存储配置
mode: "file" # 存储模式,支持 file、db、redis
file {
dir: "file_store/seata" # 文件存储目录
}
db {
datasource: "druid" # 数据源类型
dbType: "mysql" # 数据库类型
url: "jdbc:mysql://127.0.0.1:3306/seata" # 数据库 URL
user: "root" # 数据库用户名
password: "root" # 数据库密码
minConn: 5 # 最小连接数
maxConn: 30 # 最大连接数
globalTable: "global_table" # 全局事务表名
branchTable: "branch_table" # 分支事务表名
lockTable: "lock_table" # 锁表名
}
}

lock {
# 锁配置
mode: "file" # 锁模式,支持 file、db、redis
}

recovery {
# 事务恢复配置
committingRetryPeriod: 1000 # 提交重试间隔(毫秒)
asynCommittingRetryPeriod: 1000 # 异步提交重试间隔(毫秒)
rollbackingRetryPeriod: 1000 # 回滚重试间隔(毫秒)
timeoutRetryPeriod: 1000 # 超时重试间隔(毫秒)
}

transaction {
# 全局事务配置
undo.dataValidation: true # 是否开启 Undo 数据验证
undo.logSerialization: "jackson" # Undo 日志序列化方式
undo.logTable: "undo_log" # Undo 日志表名
}

support {
# 支持配置
spring {
datasource.autoproxy: false # 是否开启数据源自动代理
}
}

添加数据库表

SEATA AT 模式需要 UNDO_LOG 表。

对于undo_log表,是用来记录中间数据的,若各个微服务子项目共用一个数据库,那么只创建一个undo_log表即可。若各个微服务子项目有各自的数据库,那么就需要在每个数据库中创建undo_log表。

每个版本,不同的数据库对应的创建语句可能有所不同,具体根据以下地址获取:

1
2
# 修改对应的版本访问即可(v1.6.1)
https://github.com/apache/incubator-seata/tree/v1.6.1/script/client/at/db

以下是Seata v1.6.1 mysql 对应的undo_log创建语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- for AT mode you must to init this sql for you business database. the seata server not need it.
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';

测试

TC即调用各个子服务的加了注解@GlobalTransactional的服务应用。

在对应的TCService层添加注解@GlobalTransactional即可。

其他调用的服务有事务注解@Transactional即可。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
@GlobalTransactional
@Override
public void buyItem(Long userId, Long itemId, Integer itemCount) {
// 1.减库存

itemClient.deductStock(itemId, itemCount);
// 2.生成订单
BigDecimal price = BigDecimal.valueOf(10.0);
BigDecimal totalPrice = price.multiply(BigDecimal.valueOf(itemCount));
orderClient.createOrder(userId, itemId, itemCount, price.doubleValue(), totalPrice.doubleValue());
// 3.扣款
userClient.deductMoney(userId, totalPrice.doubleValue());
}

调用此服务时,会先调用商品服务,扣减商品库存,然后调用订单服务创建订单,最后调用用户服务扣减余额。在此期间,任何一个服务出现错误都之前的数据都将执行回滚操作。Seata通过事务锁确保一致性,而非数据库表锁。

Seata 模式

AT模式【默认】

官方文档关于AT模式的介绍

此模式基于二阶提交协议

两个进程同时进入事务的情况下:

有两个全局事务TX1,TX2,都是对同一张表进行减库存操作。

一阶段:

TX1先开启本地事务,获取并创建原始数据快照,更新数据,获取全局锁,提交本地事务,释放本地锁。

TX2先开启本地事务,获取并创建原始数据快照,更新数据,等待获取TX1全局锁,获取全局锁,提交本地事务,释放本地锁。

二阶段:

TX1执行期间无异常,释放全局锁。TX2得到全局锁,提交本地事务。

TX1执行异常,重新获取本地锁,进行反向补偿的更新操作,实现分支的回滚。TX2还在等待全局锁,而且持有的本地锁未释放。TX1会进行分支回滚重试,知道TX2全局锁等待超时,释放本地锁后,执行回滚。

AT 分支的工作过程

一阶段:

过程:

1、解析 SQL:得到 SQL 的类型(UPDATE),表(product),条件(where name = ‘TXC’)等相关的信息。

2、查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。

1
select id, name, since from product where name = 'TXC';

得到前镜像:

id name since
1 TXC 2014

3、执行业务 SQL:更新这条记录的 name 为 ‘GTS’。

4、查询后镜像:根据前镜像的结果,通过 主键 定位数据。

1
select id, name, since from product where id = 1;

得到后镜像:

id name since
1 GTS 2014

5、插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{
"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 的相关信息生成并执行回滚的语句:

1
update product set name = 'TXC' where id = 1;

5、提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。

二阶段-提交

  1. 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
  2. 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。

示例:

1、正常提交成功的情况:

业务服务@GlobalTransactional控制台输出:(hmall-service

1
2
3
2025-03-21 16:06:35.184  INFO 23500 --- [io-8079-exec-10] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [192.168.56.1:8091:2351510230618673165]
2025-03-21 16:06:35.730 INFO 23500 --- [io-8079-exec-10] i.seata.tm.api.DefaultGlobalTransaction : Suspending current transaction, xid = 192.168.56.1:8091:2351510230618673165
2025-03-21 16:06:35.730 INFO 23500 --- [io-8079-exec-10] i.seata.tm.api.DefaultGlobalTransaction : [192.168.56.1:8091:2351510230618673165] commit status: Committed

库存服务控制台输出:(item-service)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2025-03-21 16:06:35.190 DEBUG 21832 --- [nio-8083-exec-7] c.h.item.mapper.ItemMapper.selectById    : ==>  Preparing: SELECT id,name,stock,version,deleted FROM t_item WHERE id=? AND deleted=0
2025-03-21 16:06:35.191 DEBUG 21832 --- [nio-8083-exec-7] c.h.item.mapper.ItemMapper.selectById : ==> Parameters: 3(Long)
2025-03-21 16:06:35.194 DEBUG 21832 --- [nio-8083-exec-7] c.h.item.mapper.ItemMapper.selectById : <== Total: 1
2025-03-21 16:06:35.195 DEBUG 21832 --- [nio-8083-exec-7] c.h.item.mapper.ItemMapper.updateById : ==> Preparing: UPDATE t_item SET name=?, stock=?, version=? WHERE id=? AND version=? AND deleted=0
2025-03-21 16:06:35.196 DEBUG 21832 --- [nio-8083-exec-7] c.h.item.mapper.ItemMapper.updateById : ==> Parameters: 测试商品(String), 93(Integer), 8(Integer), 3(Long), 7(Integer)
2025-03-21 16:06:35.209 DEBUG 21832 --- [nio-8083-exec-7] c.h.item.mapper.ItemMapper.updateById : <== Updates: 1
2025-03-21 16:06:35.209 INFO 21832 --- [nio-8083-exec-7] c.h.item.service.impl.ItemServiceImpl : 扣减库存成功,商品id:3,商品库存:94, 订单商品数量:1,剩余库存:93
2025-03-21 16:06:35.218 DEBUG 21832 --- [nio-8083-exec-7] com.hmall.item.advice.AopAdvice : ======================================
2025-03-21 16:06:35.218 DEBUG 21832 --- [nio-8083-exec-7] com.hmall.item.advice.AopAdvice : 执行方法 >>> deductStock
2025-03-21 16:06:35.218 DEBUG 21832 --- [nio-8083-exec-7] com.hmall.item.advice.AopAdvice : 方法参数 >>> [3, 1]
2025-03-21 16:06:35.218 DEBUG 21832 --- [nio-8083-exec-7] com.hmall.item.advice.AopAdvice : 运行时间 >>> 30ms
2025-03-21 16:06:35.218 DEBUG 21832 --- [nio-8083-exec-7] com.hmall.item.advice.AopAdvice : ======================================
2025-03-21 16:06:36.472 INFO 21832 --- [h_RMROLE_1_5_24] i.s.c.r.p.c.RmBranchCommitProcessor : rm client handle branch commit process:xid=192.168.56.1:8091:2351510230618673165,branchId=2351510230618673166,branchType=AT,resourceId=jdbc:mysql://localhost:3306/hmall,applicationData={"autoCommit":false}
2025-03-21 16:06:36.472 INFO 21832 --- [h_RMROLE_1_5_24] io.seata.rm.AbstractRMHandler : Branch committing: 192.168.56.1:8091:2351510230618673165 2351510230618673166 jdbc:mysql://localhost:3306/hmall {"autoCommit":false}
2025-03-21 16:06:36.472 INFO 21832 --- [h_RMROLE_1_5_24] io.seata.rm.AbstractRMHandler : Branch commit result: PhaseTwo_Committed

订单服务控制台输出:(order-serivce

1
2
3
4
2025-03-21 16:06:35.226  INFO 15952 --- [nio-8082-exec-3] c.h.order.service.impl.OrderServiceImpl  : 创建订单成功: OrderDO(id=202503211606355, userId=1, itemId=3, itemCount=1, itemPrice=10.0, totalPrice=10.0, createTime=Fri Mar 21 16:06:35 CST 2025, version=null, deleted=null)
2025-03-21 16:06:36.475 INFO 15952 --- [h_RMROLE_1_2_24] i.s.c.r.p.c.RmBranchCommitProcessor : rm client handle branch commit process:xid=192.168.56.1:8091:2351510230618673165,branchId=2351510230618673167,branchType=AT,resourceId=jdbc:mysql://localhost:3306/hmall,applicationData={"autoCommit":false}
2025-03-21 16:06:36.476 INFO 15952 --- [h_RMROLE_1_2_24] io.seata.rm.AbstractRMHandler : Branch committing: 192.168.56.1:8091:2351510230618673165 2351510230618673167 jdbc:mysql://localhost:3306/hmall {"autoCommit":false}
2025-03-21 16:06:36.476 INFO 15952 --- [h_RMROLE_1_2_24] io.seata.rm.AbstractRMHandler : Branch commit result: PhaseTwo_Committed

用户服务控制台输出:(user-service)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2025-03-21 16:06:35.299  INFO 17088 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-03-21 16:06:35.300 INFO 17088 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2025-03-21 16:06:35.302 INFO 17088 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2025-03-21 16:06:35.381 DEBUG 17088 --- [nio-8081-exec-1] c.h.user.mapper.UserMapper.selectById : ==> Preparing: SELECT id,username,password,money,birthday,gender,phone,email,status,create_time,update_time,delete_time,version,deleted,remark FROM t_user WHERE id=? AND deleted=0
2025-03-21 16:06:35.466 DEBUG 17088 --- [nio-8081-exec-1] c.h.user.mapper.UserMapper.selectById : ==> Parameters: 1(Long)
2025-03-21 16:06:35.481 DEBUG 17088 --- [nio-8081-exec-1] c.h.user.mapper.UserMapper.selectById : <== Total: 1
2025-03-21 16:06:35.538 DEBUG 17088 --- [nio-8081-exec-1] c.h.user.mapper.UserMapper.updateById : ==> Preparing: UPDATE t_user SET username=?, password=?, money=?, birthday=?, gender=?, phone=?, status=?, create_time=?, version=? WHERE id=? AND version=? AND deleted=0
2025-03-21 16:06:35.577 DEBUG 17088 --- [nio-8081-exec-1] c.h.user.mapper.UserMapper.updateById : ==> Parameters: peter(String), 123(String), 750.0(BigDecimal), 2025-03-12 17:07:12.0(Timestamp), 0(Integer), 13554321234(String), 0(Integer), 2025-03-12 17:07:33.0(Timestamp), 9(Integer), 1(Long), 8(Integer)
2025-03-21 16:06:35.651 DEBUG 17088 --- [nio-8081-exec-1] c.h.user.mapper.UserMapper.updateById : <== Updates: 1
2025-03-21 16:06:35.651 INFO 17088 --- [nio-8081-exec-1] c.h.user.service.impl.UserServiceImpl : 扣减余成功,用户id:1,用户余额:760.0,扣减金额:10.0,剩余余额:750.0
2025-03-21 16:06:35.714 DEBUG 17088 --- [nio-8081-exec-1] com.hmall.user.advice.AopAdvice : ======================================
2025-03-21 16:06:35.714 DEBUG 17088 --- [nio-8081-exec-1] com.hmall.user.advice.AopAdvice : 执行方法 >>> deductMoney
2025-03-21 16:06:35.714 DEBUG 17088 --- [nio-8081-exec-1] com.hmall.user.advice.AopAdvice : 方法参数 >>> [1, 10.0]
2025-03-21 16:06:35.714 DEBUG 17088 --- [nio-8081-exec-1] com.hmall.user.advice.AopAdvice : 运行时间 >>> 376ms
2025-03-21 16:06:35.714 DEBUG 17088 --- [nio-8081-exec-1] com.hmall.user.advice.AopAdvice : ======================================
2025-03-21 16:06:36.481 INFO 17088 --- [h_RMROLE_1_1_24] i.s.c.r.p.c.RmBranchCommitProcessor : rm client handle branch commit process:xid=192.168.56.1:8091:2351510230618673165,branchId=2351510230618673168,branchType=AT,resourceId=jdbc:mysql://localhost:3306/hmall,applicationData={"autoCommit":false}
2025-03-21 16:06:36.483 INFO 17088 --- [h_RMROLE_1_1_24] io.seata.rm.AbstractRMHandler : Branch committing: 192.168.56.1:8091:2351510230618673165 2351510230618673168 jdbc:mysql://localhost:3306/hmall {"autoCommit":false}
2025-03-21 16:06:36.484 INFO 17088 --- [h_RMROLE_1_1_24] io.seata.rm.AbstractRMHandler : Branch commit result: PhaseTwo_Committed

2、其中一个服务异常,其他分支执行回滚的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2025-03-21 16:14:48.432  INFO 22796 --- [nio-8083-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-03-21 16:14:48.433 INFO 22796 --- [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2025-03-21 16:14:48.434 INFO 22796 --- [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2025-03-21 16:14:48.539 DEBUG 22796 --- [nio-8083-exec-1] c.h.item.mapper.ItemMapper.selectById : ==> Preparing: SELECT id,name,stock,version,deleted FROM t_item WHERE id=? AND deleted=0
2025-03-21 16:14:48.656 DEBUG 22796 --- [nio-8083-exec-1] c.h.item.mapper.ItemMapper.selectById : ==> Parameters: 3(Long)
2025-03-21 16:14:48.671 DEBUG 22796 --- [nio-8083-exec-1] c.h.item.mapper.ItemMapper.selectById : <== Total: 1
2025-03-21 16:14:48.731 DEBUG 22796 --- [nio-8083-exec-1] c.h.item.mapper.ItemMapper.updateById : ==> Preparing: UPDATE t_item SET name=?, stock=?, version=? WHERE id=? AND version=? AND deleted=0
2025-03-21 16:14:48.752 DEBUG 22796 --- [nio-8083-exec-1] c.h.item.mapper.ItemMapper.updateById : ==> Parameters: 测试商品(String), 92(Integer), 9(Integer), 3(Long), 8(Integer)
2025-03-21 16:14:48.839 DEBUG 22796 --- [nio-8083-exec-1] c.h.item.mapper.ItemMapper.updateById : <== Updates: 1
2025-03-21 16:14:48.839 INFO 22796 --- [nio-8083-exec-1] c.h.item.service.impl.ItemServiceImpl : 扣减库存成功,商品id:3,商品库存:93, 订单商品数量:1,剩余库存:92
2025-03-21 16:14:48.914 DEBUG 22796 --- [nio-8083-exec-1] com.hmall.item.advice.AopAdvice : ======================================
2025-03-21 16:14:48.915 DEBUG 22796 --- [nio-8083-exec-1] com.hmall.item.advice.AopAdvice : 执行方法 >>> deductStock
2025-03-21 16:14:48.915 DEBUG 22796 --- [nio-8083-exec-1] com.hmall.item.advice.AopAdvice : 方法参数 >>> [3, 1]
2025-03-21 16:14:48.915 DEBUG 22796 --- [nio-8083-exec-1] com.hmall.item.advice.AopAdvice : 运行时间 >>> 436ms
2025-03-21 16:14:48.915 DEBUG 22796 --- [nio-8083-exec-1] com.hmall.item.advice.AopAdvice : ======================================
2025-03-21 16:15:49.558 INFO 22796 --- [h_RMROLE_1_1_24] i.s.c.r.p.c.RmBranchRollbackProcessor : rm handle branch rollback process:xid=192.168.56.1:8091:2351510230618673169,branchId=2351510230618673170,branchType=AT,resourceId=jdbc:mysql://localhost:3306/hmall,applicationData={"autoCommit":false}
2025-03-21 16:15:49.561 INFO 22796 --- [h_RMROLE_1_1_24] io.seata.rm.AbstractRMHandler : Branch Rollbacking: 192.168.56.1:8091:2351510230618673169 2351510230618673170 jdbc:mysql://localhost:3306/hmall
2025-03-21 16:15:49.613 INFO 22796 --- [h_RMROLE_1_1_24] i.s.r.d.undo.AbstractUndoLogManager : xid 192.168.56.1:8091:2351510230618673169 branch 2351510230618673170, undo_log deleted with GlobalFinished
2025-03-21 16:15:49.616 INFO 22796 --- [h_RMROLE_1_1_24] io.seata.rm.AbstractRMHandler : Branch Rollbacked result: PhaseTwo_Rollbacked

XA模式

官方文档关于XA模式的介绍


分布式事务Seata
https://superlovelace.top/2025/03/21/分布式事务Seata/
作者
棱境
发布于
2025年3月21日
更新于
2025年5月20日
许可协议