一、版本
-
Seata 1.5.1
-
Nacos 1.4.2
-
Mysql 5.7.36
-
redis 3.2.12
二、下载seata和nacos
-
下载nacos https://github.com/alibaba/nacos/releases/download/1.4.2/nacos-server-1.4.2.zip
-
启动nacos
-
进入/path/nacos/bin
-
sh startup.sh -m standalone
-
-
下载seata http://seata.io/zh-cn/blog/download.html
三、配置seata和nacos
-
配置seata
-
修改/path/seata/conf/application.yml
-
注意config.nacos要配置 data-id: seata.properties
-
在nacos中需要新建 data-id: seata.properties 配置
-
注意registry.nacos.cluster 配置要与seata.properties中的default_tx_group对应
-
-
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: http://127.0.0.1:8848 namespace: group: SEATA_GROUP username: nacos password: nacos ##if use MSE Nacos with auth, mutex with username/password attribute #access-key: "" #secret-key: "" data-id: seata.properties registry: # support: nacos, eureka, redis, zk, consul, etcd3, sofa type: nacos # preferred-networks: 192.168.* nacos: application: seata-server server-addr: http://127.0.0.1:8848 group: SEATA_GROUP namespace: # cluster: default cluster: seata-server username: nacos password: nacos ##if use MSE Nacos with auth, mutex with username/password attribute #access-key: "" #secret-key: "" # store: //注意存储模式会配置nacos中 # 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(db模式)
-
新建seata数据库,并把seata\script\server\db\mysql.sql导数据seata库中
-
在nacos新建seata.properties
-
-
#Transaction routing rules configuration, only for the client service.vgroupMapping.default_tx_group=seata-server #Transaction storage configuration, only for the server. The file, DB, and redis configuration values are optional. store.mode=db 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=root 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
-
配置nacos(redis模式)
-
在nacos新建seata.properties
-
备注:redis和db模式任选其一即可
-
-
#Transaction routing rules configuration, only for the client service.vgroupMapping.default_tx_group=seata-server #Transaction storage configuration, only for the server. The file, DB, and redis configuration values are optional. store.mode=redis store.redis.mode=single store.redis.single.host=127.0.0.1 store.redis.single.port=63790 store.redis.sentinel.masterName= store.redis.sentinel.sentinelHosts= store.redis.maxConn=10 store.redis.minConn=1 store.redis.maxTotal=100 store.redis.database=0 store.redis.password= store.redis.queryLimit=100
-
启动seata
-
进入seata/bin 运行 sh seata-server.sh 即可
-
备注:有人说启动redis模式需要 sh seata-server.sh -m redis 我测试时不需要制定此参数
-
配置列表
-
-
服务列表
-
-
四、整合spring cloud
-
相关依赖 pom
-
spring-boot 2.3.12
-
spring-cloud-dependencies Hoxton.SR12
-
spring-cloud-alibaba-dependencies 2.2.8.RELEASE
-
seata 1.5.1
-
nacos 1.4.2
-
-
<dependency> <artifactId>spring-boot-starter</artifactId> <groupId>org.springframework.boot</groupId> <version>2.3.12.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR12</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <exclusions> <exclusion> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> </exclusion> </exclusions> </dependency> <!-- 由于使用的nacos server是1.4.2 这里依赖1.x版本的nacos-client --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>1.4.2</version> </dependency>
-
seata相关配置文件yml
-
每个微服务都需要配置seata部分
-
注意一下配置
-
tx-service-group
-
registry.nacos.cluster
-
config.nacos.dataId
-
-
-
# nacos 配置 spring: main: allow-bean-definition-overriding: true cloud: nacos: discovery: server-addr: localhost:8848 # seata配置 seata: enabled: true application-id: coin-services tx-service-group: default_tx_group enable-auto-data-source-proxy: true data-source-proxy-mode: AT registry: type: nacos nacos: server-addr: localhost:8848 namespace: cluster: seata-server group: SEATA_GROUP username: nacos password: nacos service: vgroup-mapping: default_tx_group: seata-server config: type: nacos nacos: server-addr: localhost:8848 namespace: dataId: "seata.properties" group: SEATA_GROUP username: nacos password: nacos
-
每个微服务操作的数据库都要创建一张表 undo_log
-
CREATE TABLE `undo_log` ( `branch_id` bigint(20) 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 DEFAULT CHARSET=utf8mb4 COMMENT='AT transaction mode undo table';
-
由于seata的xid传递是基于header的,需要在微服务中创建一个拦截器
-
@Slf4j @Component public class RequestHeaderInterceptor implements RequestInterceptor{ @Override public void apply(RequestTemplate template) { String xid = RootContext.getXID(); if (StringUtils.isNotBlank(xid)) { template.header(RootContext.KEY_XID, xid); } } }
-
简单示例
-
微服务a开启一个@GlobalTransactional远程调用微服务b
-
@GlobalTransactional public Boolean testAccount(Long accountId, Long coin) { String xid = RootContext.getXID(); String xid1 = GlobalTransactionContext.getCurrentOrCreate().getXid(); log.info("refreshUserAccountTest xid={}, xid1={}", xid, xid1); //服务a入口操作 // 省略操作数据库代码 boolean result = true; //远程调用为服务器b可以成功,也有可能失败 Result<Boolean> userResult = feignBService.refreshAccountTest(accountId, coin); if (!result) { //回滚需要抛出异常 throw new Exception(2000001,"请求结果没有完全成功"); } return result; }
-
服务b为一个常规的db写库操作
-