简介
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案
Seata:https://seata.io/zh-cn/index.html
AT 模式
简介
seata:https://seata.io/zh-cn/docs/dev/mode/at-mode.html
Seata 中有三大模块,分别是 TM、RM 和 TC。其中 TM 和 RM 是作为 Seata 的客户端与业务系统集成在⼀起,TC 作为 Seata 的服务端独立部署。
TC (Transaction Coordinator)- 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
Seata管理的分布式事务的典型生命周期:
在 Seata 中,分布式事务的执行流程:
TM 开启分布式事务, TM会 向 TC 注册全局事务记录;
操作具体业务模块的数据库操作之前, RM 会向 TC 注册分支事务;
当业务操作完事后.TM会通知 TC 提交/回滚分布式事务;
TC 汇总事务信息,决定分布式事务是提交还是回滚;
TC 通知所有 RM 提交/回滚 资源,事务二阶段结束。
环境
- JDK 11
- IDEA
- seata-server 1.6.1 https://github.com/seata/seata/releases
- Nacos 1.2
准备环境
- JDK 11、IDEA、Nacos 1.2 略
启动nacos
.\startup.cmd -m standalone
seata-server 1.6.1 准备
- 下载解压seata-server 1.6.1 https://github.com/seata/seata/releases
- 新建mysql数据库,执行脚本文件
..\seata\script\server\db\mysql.sql
- COPY
application.example.yml
修改application.yml
# 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
console:
user:
username: seata
password: seata
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group : "SEATA_GROUP"
namespace: ""
username: "nacos"
password: "nacos"
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group : "SEATA_GROUP"
namespace: ""
username: "nacos"
password: "nacos"
store:
# support: file 、 db 、 redis
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=GMT
user: root
password: root
min-conn: 5
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 100
max-wait: 5000
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
- 在nacos 配置中心新建
seataServer.properties
配置文件或 上传seata 配置
配置文件位置…\seata\script\config-center
github配置文件位置
- 方式一:利用
nacos-config.sh
直接上传
sh nacos-config.sh -h 127.0.0.1
- 方式一:添加配置文件的方式
- 启动seata-server 1.6.1
- 作为服务注册到nacos注册中心
- seata控制台 http://localhost:7091/#/login 用户/密码:seata/seata
sptingboot 整合 seata1.6.1 实现分布式事务AT模式
模拟下单,增加积分,扣减库存的场景。下单超过库存,下单失败,订单数据和积分数据回滚。 bussiness、order、points、storage 相当于服务拆分,可独立注册到nacos注册中心。
CREATE TABLE `t_order` (
`id` bigint(20) NOT NULL COMMENT '订单id',
`goods_Id` int(11) DEFAULT NULL COMMENT '商品ID',
`num` int(11) DEFAULT NULL COMMENT '商品数量',
`money` decimal(10,0) DEFAULT NULL COMMENT '商品总金额',
`create_time` datetime DEFAULT NULL COMMENT '订单创建时间',
`username` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名称',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;
CREATE TABLE `t_points` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '积分ID',
`username` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '用户名',
`points` int(11) DEFAULT NULL COMMENT '用户积分',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;
CREATE TABLE `t_storage` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '库存ID',
`goods_id` int(11) DEFAULT NULL COMMENT '商品ID',
`storage` int(11) DEFAULT NULL COMMENT '库存量',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;
INSERT INTO `seata_storage`.`t_storage`(`id`, `goods_id`, `storage`) VALUES (1, 1, 100);
AT 模式在RM端需要 UNDO_LOG 表,来记录每个RM的事务信息,主要包含数据修改前,后的相关信息,用于回滚处理,所以在所有数据库中分别执行
-- 注意此处0.3.0+ 增加唯⼀索引 ux_undo_log
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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
- 父工程添加
seata
依赖
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.6.1</version>
</dependency>
- 公共模块
lagou_common_db
添加seata
依赖
<!-- 注意一定要引入对版本,要引入spring-cloud版本seata,而不是springboot版本的seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<!-- 排除掉springcloud默认的seata版本,以免版本不一致出现问题-->
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 上面排除掉了springcloud默认色seata版本,此处引入和seata-server版本对应的seata包-->
<!-- <dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.6.1</version>
</dependency>-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.6.1</version>
</dependency>
- 公共模块
lagou_common_db
添加seata
配置
# staet----------------------------seata服务配置
seata:
# 切换XA模式
enable: true
data-source-proxy-mode: AT
enable-auto-data-source-proxy: true
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: seata-server
group: SEATA_GROUP
username: nacos
password: nacos
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: seata-server
application: seata-server
group: SEATA_GROUP
username: nacos
password: nacos
service:
vgroup-mapping:
default_tx_group: default
disable-global-transaction: false
grouplist:
default: 127.0.0.1:8091
tx-service-group: default_tx_group
spring:
cloud:
alibaba:
seata:
tx-service-group: default_tx_group
logging:
level:
seata: debug
- bussiness、order、points、storage 模块配置中依赖公共模块配置(支持seata)
spring:
profiles:
active: seata
- 封装数据源代理DatasourceProxy
package com.lagou.common_db.config;
import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* @author Mrwg
* @date 2023/6/7 20:50
* @description
*/
@Configuration
public class DataSourceConfiguration {
/**
* 使⽤druid连接池
*
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
return new DruidDataSource();
}
@Primary //设置⾸选数据源对象
@Bean("dataSource")
public DataSourceProxy dataSource(DataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
}
- 启动扫描配置类,分别加载每个工程的启动类中(bussiness、order、points、storage)
@SpringBootApplication(scanBasePackages = "com.lagou",exclude = DataSourceAutoConfiguration.class)
- 添加注解
@GlobalTransactional
/**
* 商品销售
*
* @param goodsId 商品id
* @param num 销售数量
* @param username 用户名
* @param money 金额
*/
// @Transactional
@GlobalTransactional(rollbackFor = Exception.class, timeoutMills = 60000, name = "sale")
public void sale(Integer goodsId, Integer num, Double money, String username) {
//创建订单
orderServiceFeign.addOrder(idWorker.nextId(), goodsId, num, money, username);
//增加积分
pointsServiceFeign.increase(username, (int) (money / 10));
//扣减库存
storageServiceFeign.decrease(goodsId, num);
}
- 启动个服务
- seata-server控制台日志
17:57:54.481 INFO --- [ttyServerNIOWorker_1_1_24] i.s.c.r.processor.server.RegTmProcessor : TM register success,message:RegisterTMRequest{
applicationId='lagou-bussiness-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x04b67b1a, L:/127.0.0.1:8091 - R:/127.0.0.1:9728],client version:1.6.1
17:58:05.529 INFO --- [rverHandlerThread_1_1_500] i.s.c.r.processor.server.RegRmProcessor : RM register success,message:RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_bussiness', applicationId='lagou-bussiness-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x067e82dd, L:/127.0.0.1:8091 - R:/127.0.0.1:9745],client version:1.6.1
17:58:12.452 INFO --- [ttyServerNIOWorker_1_3_24] i.s.c.r.processor.server.RegTmProcessor : TM register success,message:RegisterTMRequest{
applicationId='lagou-order-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x9dd35e2f, L:/127.0.0.1:8091 - R:/127.0.0.1:9756],client version:1.6.1
17:58:15.316 INFO --- [rverHandlerThread_1_2_500] i.s.c.r.processor.server.RegRmProcessor : RM register success,message:RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_order', applicationId='lagou-order-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x7b88a875, L:/127.0.0.1:8091 - R:/127.0.0.1:9767],client version:1.6.1
17:58:25.741 INFO --- [ttyServerNIOWorker_1_5_24] i.s.c.r.processor.server.RegTmProcessor : TM register success,message:RegisterTMRequest{
applicationId='lagou-points-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x733fa529, L:/127.0.0.1:8091 - R:/127.0.0.1:9777],client version:1.6.1
17:58:28.209 INFO --- [rverHandlerThread_1_3_500] i.s.c.r.processor.server.RegRmProcessor : RM register success,message:RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_points', applicationId='lagou-points-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x3b82fe76, L:/127.0.0.1:8091 - R:/127.0.0.1:9782],client version:1.6.1
17:58:44.460 INFO --- [ttyServerNIOWorker_1_7_24] i.s.c.r.processor.server.RegTmProcessor : TM register success,message:RegisterTMRequest{
applicationId='lagou-storage-service', transactionServiceGroup='default_tx_group'},channel:[id: 0x8939f9b1, L:/127.0.0.1:8091 - R:/127.0.0.1:9825],client version:1.6.1
17:58:47.678 INFO --- [rverHandlerThread_1_4_500] i.s.c.r.processor.server.RegRmProcessor : RM register success,message:RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_storage', applicationId='lagou-storage-service', transactionServiceGroup='default_tx_group'},channel:[id: 0xb2be7179, L:/127.0.0.1:8091 - R:/127.0.0.1:9839],client version:1.6.1
- nacos
- 本地各服务日志
will connect to 127.0.0.1:8091
2023-06-08 18:04:04.638 INFO 10676 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : RM will register :jdbc:mysql://localhost:3306/seata_bussiness
2023-06-08 18:04:04.638 INFO 10676 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:RMROLE,address:127.0.0.1:8091,msg:< RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_bussiness', applicationId='lagou-bussiness-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:04.654 INFO 10676 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : register RM success. client version:1.6.1, server version:1.6.1,channel:[id: 0xa18c6e4b, L:/127.0.0.1:10510 - R:/127.0.0.1:8091]
2023-06-08 18:04:04.655 INFO 10676 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 11 ms, version:1.6.1,role:RMROLE,channel:[id: 0xa18c6e4b, L:/127.0.0.1:10510 - R:/127.0.0.1:8091]
2023-06-08 18:04:08.975 INFO 10676 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager : will connect to 127.0.0.1:8091
2023-06-08 18:04:08.975 INFO 10676 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:TMROLE,address:127.0.0.1:8091,msg:< RegisterTMRequest{
applicationId='lagou-bussiness-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:08.990 INFO 10676 --- [eoutChecker_1_1] i.s.c.rpc.netty.TmNettyRemotingClient : register TM success. client version:1.6.1, server version:1.6.1,channel:[id: 0x900d602b, L:/127.0.0.1:10520 - R:/127.0.0.1:8091]
2023-06-08 18:04:08.990 INFO 10676 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 9 ms, version:1.6.1,role:TMROLE,channel:[id: 0x900d602b, L:/127.0.0.1:10520 - R:/127.0.0.1:8091]
2023-06-08 18:06:58.277 INFO 10676 --- [h_RMROLE_1_1_24] i.s.c.r.p.client.RmUndoLogProcessor : rm handle undo log process:UndoLogDeleteRequest{
resourceId='jdbc:mysql://localhost:3306/seata_bussiness', saveDays=7, branchType=AT}
will connect to 127.0.0.1:8091
2023-06-08 18:04:02.548 INFO 30184 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : RM will register :jdbc:mysql://localhost:3306/seata_order
2023-06-08 18:04:02.548 INFO 30184 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:RMROLE,address:127.0.0.1:8091,msg:< RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_order', applicationId='lagou-order-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:04.568 INFO 30184 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : register RM success. client version:1.6.1, server version:1.6.1,channel:[id: 0xe214ddcf, L:/127.0.0.1:10504 - R:/127.0.0.1:8091]
2023-06-08 18:04:04.569 INFO 30184 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 12 ms, version:1.6.1,role:RMROLE,channel:[id: 0xe214ddcf, L:/127.0.0.1:10504 - R:/127.0.0.1:8091]
2023-06-08 18:04:08.396 INFO 30184 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager : will connect to 127.0.0.1:8091
2023-06-08 18:04:08.396 INFO 30184 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:TMROLE,address:127.0.0.1:8091,msg:< RegisterTMRequest{
applicationId='lagou-order-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:08.412 INFO 30184 --- [eoutChecker_1_1] i.s.c.rpc.netty.TmNettyRemotingClient : register TM success. client version:1.6.1, server version:1.6.1,channel:[id: 0xb1003efc, L:/127.0.0.1:10515 - R:/127.0.0.1:8091]
2023-06-08 18:04:08.412 INFO 30184 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 10 ms, version:1.6.1,role:TMROLE,channel:[id: 0xb1003efc, L:/127.0.0.1:10515 - R:/127.0.0.1:8091]
2023-06-08 18:06:58.341 INFO 30184 --- [h_RMROLE_1_1_24] i.s.c.r.p.client.RmUndoLogProcessor : rm handle undo log process:UndoLogDeleteRequest{
resourceId='jdbc:mysql://localhost:3306/seata_order', saveDays=7, branchType=AT}
2023-06-08 18:04:02.301 INFO 26008 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager : will connect to 127.0.0.1:8091
2023-06-08 18:04:02.301 INFO 26008 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:TMROLE,address:127.0.0.1:8091,msg:< RegisterTMRequest{
applicationId='lagou-points-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:04.504 INFO 26008 --- [eoutChecker_1_1] i.s.c.rpc.netty.TmNettyRemotingClient : register TM success. client version:1.6.1, server version:1.6.1,channel:[id: 0x4a99ba24, L:/127.0.0.1:10503 - R:/127.0.0.1:8091]
2023-06-08 18:04:04.504 INFO 26008 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 194 ms, version:1.6.1,role:TMROLE,channel:[id: 0x4a99ba24, L:/127.0.0.1:10503 - R:/127.0.0.1:8091]
2023-06-08 18:04:05.851 INFO 26008 --- [eoutChecker_2_1] i.s.c.r.netty.NettyClientChannelManager : will connect to 127.0.0.1:8091
2023-06-08 18:04:05.851 INFO 26008 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : RM will register :jdbc:mysql://localhost:3306/seata_points
2023-06-08 18:04:05.851 INFO 26008 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:RMROLE,address:127.0.0.1:8091,msg:< RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_points', applicationId='lagou-points-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:05.868 INFO 26008 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : register RM success. client version:1.6.1, server version:1.6.1,channel:[id: 0x3d960a16, L:/127.0.0.1:10512 - R:/127.0.0.1:8091]
2023-06-08 18:04:05.868 INFO 26008 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 11 ms, version:1.6.1,role:RMROLE,channel:[id: 0x3d960a16, L:/127.0.0.1:10512 - R:/127.0.0.1:8091]
2023-06-08 18:06:58.340 INFO 26008 --- [h_RMROLE_1_1_24] i.s.c.r.p.client.RmUndoLogProcessor : rm handle undo log process:UndoLogDeleteRequest{
resourceId='jdbc:mysql://localhost:3306/seata_points', saveDays=7, branchType=AT}
2023-06-08 18:04:04.537 INFO 20412 --- [eoutChecker_2_1] i.s.c.r.netty.NettyClientChannelManager : will connect to 127.0.0.1:8091
2023-06-08 18:04:04.537 INFO 20412 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : RM will register :jdbc:mysql://localhost:3306/seata_storage
2023-06-08 18:04:04.537 INFO 20412 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:RMROLE,address:127.0.0.1:8091,msg:< RegisterRMRequest{
resourceIds='jdbc:mysql://localhost:3306/seata_storage', applicationId='lagou-storage-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:04.561 INFO 20412 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient : register RM success. client version:1.6.1, server version:1.6.1,channel:[id: 0x3125c6c4, L:/127.0.0.1:10509 - R:/127.0.0.1:8091]
2023-06-08 18:04:04.562 INFO 20412 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 19 ms, version:1.6.1,role:RMROLE,channel:[id: 0x3125c6c4, L:/127.0.0.1:10509 - R:/127.0.0.1:8091]
2023-06-08 18:04:08.824 INFO 20412 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager : will connect to 127.0.0.1:8091
2023-06-08 18:04:08.824 INFO 20412 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : NettyPool create channel to transactionRole:TMROLE,address:127.0.0.1:8091,msg:< RegisterTMRequest{
applicationId='lagou-storage-service', transactionServiceGroup='default_tx_group'} >
2023-06-08 18:04:08.838 INFO 20412 --- [eoutChecker_1_1] i.s.c.rpc.netty.TmNettyRemotingClient : register TM success. client version:1.6.1, server version:1.6.1,channel:[id: 0x8a3d9ec4, L:/127.0.0.1:10519 - R:/127.0.0.1:8091]
2023-06-08 18:04:08.838 INFO 20412 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory : register success, cost 9 ms, version:1.6.1,role:TMROLE,channel:[id: 0x8a3d9ec4, L:/127.0.0.1:10519 - R:/127.0.0.1:8091]
2023-06-08 18:06:58.276 INFO 20412 --- [h_RMROLE_1_1_24] i.s.c.r.p.client.RmUndoLogProcessor : rm handle undo log process:UndoLogDeleteRequest{
resourceId='jdbc:mysql://localhost:3306/seata_storage', saveDays=7, branchType=AT}
验证
库存为100,下单超过100即可触发分布式事务回滚。
http://localhost:8000/test1 正常下单,加积分,减库存。
http://localhost:8000/test2 异常下单,库存不足,回滚订单和积分。
- http://localhost:8000/test1 正常下单,加积分,减库存。
- http://localhost:8000/test2 异常下单,库存不足,回滚订单和积分。
没有产生订单和积分数据,是我们期望的结果
seata 控制台全局事务和分支事务回滚日志
- 断点可查看到seata 和 undo_log 数据变化
问题
可能遇到的问题? 事务无法回滚?
参考:Seata实战安装部署与Spring Cloud应用
参考:Seata整合SpringBoot和Mybatis