版本:
Springboot:2.2.0
SpringCloud: 2020.0.3
Seata: 1.4
复制代码
本文章demo地址:gitee.com/TZWw/spring…
1)地址:seata.io/zh-cn/blog/…
2)在conf文件夹修改file.conf文件
3)向本地数据库导入seata需要的表
CREATE TABLE `branch_table` (
`branch_id` bigint NOT NULL,
`xid` varchar(128) NOT NULL,
`transaction_id` bigint DEFAULT NULL,
`resource_group_id` varchar(32) DEFAULT NULL,
`resource_id` varchar(256) DEFAULT NULL,
`lock_key` varchar(128) DEFAULT NULL,
`branch_type` varchar(8) DEFAULT NULL,
`status` tinyint DEFAULT NULL,
`client_id` varchar(64) DEFAULT NULL,
`application_data` varchar(2000) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
PRIMARY KEY (`branch_id`),
KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
复制代码
CREATE TABLE `global_table` (
`xid` varchar(128) NOT NULL,
`transaction_id` bigint DEFAULT NULL,
`status` tinyint NOT NULL,
`application_id` varchar(32) DEFAULT NULL,
`transaction_service_group` varchar(32) DEFAULT NULL,
`transaction_name` varchar(128) DEFAULT NULL,
`timeout` int DEFAULT NULL,
`begin_time` bigint DEFAULT NULL,
`application_data` varchar(2000) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
PRIMARY KEY (`xid`),
KEY `idx_gmt_modified_status` (`gmt_modified`,`status`),
KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
复制代码
CREATE TABLE `lock_table` (
`row_key` varchar(128) NOT NULL,
`xid` varchar(96) DEFAULT NULL,
`transaction_id` mediumtext,
`branch_id` mediumtext,
`resource_id` varchar(256) DEFAULT NULL,
`table_name` varchar(32) DEFAULT NULL,
`pk` varchar(36) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
PRIMARY KEY (`row_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
复制代码
4)修改registry.conf文件
5)将seata配置信息添加到nacos配置中心
1.启动本地的nacos服务 2.下载config.txt和nacos-config.sh两个文件 github.com/seata/seata… github.com/seata/seata… 3.然后执行nacos-config.sh脚本
4.查看nacos中添加成功的配置
6)启动seata
进入bin目录下,执行 ./seata-server.sh 出现下图即为启动成功
1)创建one和two数据库,每个数据库都必须包含undo_log表
CREATE TABLE `count` (
`id` int NOT NULL AUTO_INCREMENT,
`count` int DEFAULT NULL COMMENT '库存',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`branch_id` bigint NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int 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=20 DEFAULT CHARSET=utf8mb3;
复制代码
CREATE TABLE `order` (
`id` int NOT NULL AUTO_INCREMENT,
`order_count` int DEFAULT NULL,
`product_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`branch_id` bigint NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int 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=3 DEFAULT CHARSET=utf8mb3;
复制代码
此处省略创建服务过程。。。
maven父工程依赖
4.0.0
pom
serviceone
servicetwo
servicecommon
org.springframework.boot
spring-boot-starter-parent
2.5.5
com.example
demo2
0.0.1-SNAPSHOT
demo2
Demo project for Spring Boot
1.8
2020.0.3
2021.1
com.alibaba
druid
1.1.9
org.springframework.boot
spring-boot-starter-test
2.3.3.RELEASE
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.0
org.springframework.cloud
spring-cloud-context
2.2.3.RELEASE
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2021.1
pom
import
mysql
mysql-connector-java
8.0.26
pom
import
org.springframework.boot
spring-boot-starter-log4j
1.3.8.RELEASE
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
复制代码
bootstrap.yml文件
# Spring
spring:
application:
# 应用名称
name: service-one
profiles:
# 环境配置
active: dev
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: localhost:8848
# namespace: 3d25ad9f-6b5a-4f1a-a4a7-0bbba90a00fa
group: SEATA_GROUP
config:
# 配置中心地址
server-addr: localhost:8848
namespace: 8221aa53-c648-4c6a-8a41-0c3a685ba58e
# # 配置文件格式
file-extension: yml
# # 共享配置
# shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#
seata:
tx-service-group: my_test_tx_group
registry:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
group: ${spring.cloud.nacos.discovery.group}
# namespace: 6c990727-93b2-4081-a8c6-6b015c56eda2
config:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
group: ${spring.cloud.nacos.discovery.group}
# namespace: 6db428d4-e7a3-4dd3-be02-283960e0e704
service:
vgroup-mapping:
my_test_tx_group: default
复制代码
nacos中one的配置(service-one-dev.yml):
# Spring
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/service-one?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456789
server:
port: 8085
# Mybatis配置
mybatis:
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath:mapper/**/*.xml
httpclient:
enabled: true
复制代码
one服务依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
org.springframework.cloud
spring-cloud-loadbalancer
org.springframework.cloud
spring-cloud-starter-bootstrap
org.springframework.cloud
spring-cloud-context
3.0.2
mysql
mysql-connector-java
org.springframework.cloud
spring-cloud-starter-openfeign
2.2.3.RELEASE
cn.hutool
hutool-all
5.6.6
com.alibaba
druid-spring-boot-starter
1.2.6
org.springframework.boot
spring-boot-starter-log4j
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
io.github.openfeign
feign-httpclient
复制代码
controller :
@GetMapping("/insertOpt")
public CommonResult insertOpt() {
try {
countService.insertOpt();
return new CommonResult(true, "成功", null);
} catch (Exception e) {
return new CommonResult(false, "失败", null);
}
}
复制代码
serviceImpl
@Override
@GlobalTransactional(rollbackFor = Exception.class, name = "insertOpt")
public CommonResult insertOpt() {
Count count = new Count();
count.setCount(12);
int insert = this.countDao.insert(count);
if (insert == 0) {
throw new RuntimeException("first失败");
}
Order order = new Order();
order.setOrderCount(12);
order.setProductId(12L);
CommonResult commonResult = remoteServiceTwo.insertOne(order);
if (!commonResult.getBool()){
throw new RuntimeException("操作远程失败!");
}
Map map = new HashMap<>(16);
map.put("count", insert);
map.put("order", commonResult);
System.err.println("map===="+ map.toString());
return new CommonResult(true, "成功", map);
}
复制代码
feign请求
@FeignClient(value = "service-two")
public interface RemoteServiceTwo {
@PostMapping("/order/insertOne")
public CommonResult insertOne(Order order);
}
复制代码
bootstrap.yml
# Spring
spring:
application:
# 应用名称
name: service-two
profiles:
# 环境配置
active: dev
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: localhost:8848
# namespace: 3d25ad9f-6b5a-4f1a-a4a7-0bbba90a00fa
group: SEATA_GROUP
config:
# 配置中心地址
server-addr: localhost:8848
namespace: 8221aa53-c648-4c6a-8a41-0c3a685ba58e
# # 配置文件格式
file-extension: yml
# # 共享配置
# shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
seata:
tx-service-group: my_test_tx_group
registry:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
group: ${spring.cloud.nacos.discovery.group}
# namespace: 6c990727-93b2-4081-a8c6-6b015c56eda2
config:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
group: ${spring.cloud.nacos.discovery.group}
service:
vgroup-mapping:
my_test_tx_group: default
复制代码
pom.xml 依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
org.springframework.cloud
spring-cloud-loadbalancer
org.springframework.cloud
spring-cloud-starter-bootstrap
org.springframework.cloud
spring-cloud-context
3.0.2
mysql
mysql-connector-java
org.springframework.cloud
spring-cloud-starter-openfeign
2.2.3.RELEASE
cn.hutool
hutool-all
5.6.6
com.example
servicecommon
0.0.1-SNAPSHOT
com.alibaba
druid-spring-boot-starter
1.2.6
org.springframework.boot
spring-boot-starter-log4j
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
复制代码
nacos中two服务的配置service-two-dev.yml
# Spring
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/service-two?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456789
server:
port: 8086
# Mybatis配置
mybatis:
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath:mapper/**/*.xml
# 我使用的这个版本这一步可以忽略
httpclient:
enabled: true
复制代码
two服务controller
@PostMapping("insertOne")
public CommonResult selectOne(@RequestBody Order order) {
try {
this.orderService.insert(order);
return new CommonResult(true, "成功", null);
} catch (Exception e) {
StaticLog.error("失败:======{}", e);
return new CommonResult(false, "失败", null);
}
}
复制代码
serviceImpl
/**
* 新增数据
*
* @param order 实例对象
* @return 实例对象
*/
@Override
public Order insert(Order order) {
// int a = 1/0; // 此处是为了出现错误,看seata是否会回滚
this.orderDao.insert(order);
return order;
}
复制代码
浏览器操作
serviceone的日志
servicetwo日志
数据库结果-插入成功 (清空数据库进行插入失败操作)
1) 插入失败,进行回滚---在servicetwo业务代码上添加一个报错代码
浏览器操作
serviceone 日志(进行了回滚)
servicetwo 日志
数据库数据