springCloud整合seata,以nacos作为配置中心
一. SEATA下载
https://github.com/apache/incubator-seata/releases/tag/v2.0.0
二. SEATA配置修改
1. seate->config->application.yml配置
server:
port: 7091
spring:
application:
name: seata-server
logging:
config: classpath:logback-spring.xml
file:
path: ${log.home:${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:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: 6adbec40-7754-4fc1-88d7-1f9232c269e6
# seata的配置文件在nacos中都要使用这个分组
group: SEATA_GROUP
username: nacos
password: nacos
context-path:
# 存在nacos的seata数据库的配置文件
data-id: seata.properties
registry:
type: nacos
preferred-networks: 30.240.*
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace: 6adbec40-7754-4fc1-88d7-1f9232c269e6
cluster: default
username: nacos
password: nacos
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
store:
mode: file
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login,/metadata/v1/**
2. 创建seata需要的数据库
3. 在各个TM(使用分布式事务的服务)新建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服务
启动SEATA之后,nacos会注册这个服务:
四. springBoot项目整合SEATA
1. 依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<!-- 方便单据指定SEATA版本,可以排除 -->
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
2. springBoot的配置文件
seata:
enabled: true
#服务名(多个TM一定唯一)
application-id: product
#事务组(同个SEATA管理的TM保持一致)
tx-service-group: my_tx_group
enable-auto-data-source-proxy: true
use-jdk-proxy: false
registry:
type: nacos
nacos:
#nacos的地址、命名空间、分组要和seata服务中的配置一致
application: seata-server
server-addr: 127.0.0.1:8848
namespace: 6adbec40-7754-4fc1-88d7-1f9232c269e6
group: SEATA_GROUP
username: nacos
password: nacos
service:
vgroup-mapping:
# 属性名为事务组的属性值;会在nacos创建一个名称为service.vgroupMapping.my_tx_group的配置文件,文件内容为default,否则springboot项目启动保存
my_tx_group: default
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: 6adbec40-7754-4fc1-88d7-1f9232c269e6
group: SEATA_GROUP
username: nacos
password: nacos
data-id: seata.properties
3. nacos增加2个配置文件,配合springboot项目使用
- seata.properties(名称和springboot的data-id和seata的config文件夹下的application.yml一致即可)
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
- service.vgroupMapping.my_tx_group(springboot项目配置的属性名service.vgroupMapping和属性值my_tx_group拼接;”my_tx_group“为自定义字符串和springboot的配置文件一致即可)
default
五. 测试
1. 至少启动2个项目验证
前置条件是分布式服务:
- Order服务
@GetMapping("order/feign/test")
// seata AT模式的分布式事务注解
@GlobalTransactional(rollbackFor = Exception.class)
public String feignTest(@RequestParam("ids") String ids) {
// 通过feign远程调用商品服务更新操作
List<User> cartFromProductServer = productFeignController.updateProdcutFromProductServer(ids);
// 本服务更新
userMapper.updateOrder(13,"测试分布式事务-order");
// 认为异常
System.out.println(1/0);
return cartFromProductServer == null ? "fail" : cartFromProductServer.toString();
}
- product服务
正常处理updateProdcutFromProductServer。
结果:
order服务人为异常抛出,product正常调用但由于order异常同步回滚。