赞
踩
seata官网:http://seata.io/zh-cn/index.html
seata-server: https://github.com/seata/seata/releases
SpringCloud整合Seata出现异常数据未回滚的解决方案
下载指定版本seata-server,本案例使用v1.6.1
版本。
server: port: 7091 spring: application: name: seata-server # seata-server服务名 logging: config: classpath:logback-spring.xml file: path: ${user.home}/seata/runlogs # 指定日志路径 extend: logstash-appender: destination: 127.0.0.1:4560 kafka-appender: bootstrap-servers: 127.0.0.1:9092 topic: logback_to_logstash # seata可视化web界面账号密码 console: user: username: seata password: seata seata: # 配置中心 config: # support: nacos, consul, apollo, zk, etcd3 type: nacos # 指定配置中心为nacos nacos: server-addr: 127.0.0.1:8848 # nacos的ip端口 group: DEFAULT_GROUP # 对应的组,默认为DEFAULT_GROUP namespace: a090b021-160c-42fb-98de-b1f9a5619d97 # 对应的命名空间,在nacos中配置 username: nacos password: nacos data-id: seataServer.properties # nacos中存放seata的配置文件,后面会提该文件的使用方式,相当于seata服务启动的时候需要注册到nacos,并使用nacos中的配置文件 # 注册中心与上述config同理 registry: # support: nacos, eureka, redis, zk, consul, etcd3, sofa type: nacos nacos: application: seata-server server-addr: 127.0.0.1:8848 namespace: a090b021-160c-42fb-98de-b1f9a5619d97 group: DEFAULT_GROUP cluster: default username: nacos password: nacos security: secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017 tokenValidityInMilliseconds: 1800000 ignore: urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
【注意】
seata.config.type
与seata.registry.type
都要修改为nacos
config
与registry
中nacos的配置,其中namespace
与group
须提前在nacos中进行配置新建namespace
命名空间,需与上述seata-server
的application.yml
中配置一致
在上述namespace
下新建application.yml
中seata.config.nacos.data-id
提到的配置文件:seataServer.properties
seataServer.properties 已删除无用配置
#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html #Transport configuration, for client and server transport.type=TCP transport.server=NIO transport.heartbeat=true transport.enableTmClientBatchSendRequest=false transport.enableRmClientBatchSendRequest=true transport.enableTcServerBatchSendResponse=false transport.rpcRmRequestTimeout=30000 transport.rpcTmRequestTimeout=30000 transport.rpcTcRequestTimeout=30000 transport.threadFactory.bossThreadPrefix=NettyBoss transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler transport.threadFactory.shareBossWorker=false transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector transport.threadFactory.clientSelectorThreadSize=1 transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread transport.threadFactory.bossThreadSize=1 transport.threadFactory.workerThreadSize=default transport.shutdown.wait=3 transport.serialization=seata transport.compressor=none #Transaction routing rules configuration, only for the client # 此处的mygroup名字可以自定义,只修改这个值即可 service.vgroupMapping.mygroup=default #If you use a registry, you can ignore it service.default.grouplist=127.0.0.1:8091 service.enableDegrade=false service.disableGlobalTransaction=false #Transaction rule configuration, only for the client client.rm.asyncCommitBufferLimit=10000 client.rm.lock.retryInterval=10 client.rm.lock.retryTimes=30 client.rm.lock.retryPolicyBranchRollbackOnConflict=true client.rm.reportRetryCount=5 client.rm.tableMetaCheckEnable=true client.rm.tableMetaCheckerInterval=60000 client.rm.sqlParserType=druid client.rm.reportSuccessEnable=false client.rm.sagaBranchRegisterEnable=false client.rm.sagaJsonParser=fastjson client.rm.tccActionInterceptorOrder=-2147482648 client.tm.commitRetryCount=5 client.tm.rollbackRetryCount=5 client.tm.defaultGlobalTransactionTimeout=60000 client.tm.degradeCheck=false client.tm.degradeCheckAllowTimes=10 client.tm.degradeCheckPeriod=2000 client.tm.interceptorOrder=-2147482648 client.undo.dataValidation=true client.undo.logSerialization=jackson client.undo.onlyCareUpdateColumns=true server.undo.logSaveDays=7 server.undo.logDeletePeriod=86400000 client.undo.logTable=undo_log client.undo.compress.enable=true client.undo.compress.type=zip client.undo.compress.threshold=64k #For TCC transaction mode tcc.fence.logTableName=tcc_fence_log tcc.fence.cleanPeriod=1h #Log rule configuration, for client and server log.exceptionRate=100 #Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional. # 默认为file,一定要改为db,我们自己的服务启动会连接不到seata store.mode=db store.lock.mode=db store.session.mode=db #Used for password encryption #These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block. # 修改mysql的配置 store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.cj.jdbc.Driver # 指定seata的数据库,下面会提 store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true store.db.user=root store.db.password=banmajio 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 #Transaction rule configuration, only for the server server.recovery.committingRetryPeriod=1000 server.recovery.asynCommittingRetryPeriod=1000 server.recovery.rollbackingRetryPeriod=1000 server.recovery.timeoutRetryPeriod=1000 server.maxCommitRetryTimeout=-1 server.maxRollbackRetryTimeout=-1 server.rollbackRetryTimeoutUnlockEnable=false server.distributedLockExpireTime=10000 server.xaerNotaRetryTimeout=60000 server.session.branchAsyncQueueSize=5000 server.session.enableBranchAsyncRemove=false server.enableParallelRequestHandle=false #Metrics configuration, only for the server metrics.enabled=false metrics.registryType=compact metrics.exporterList=prometheus metrics.exporterPrometheusPort=9898
service.vgroupMapping.mygroup=default
该值,其中mygroup可以自定义,后面我们自己的服务启动时,配置文件中需要指定该group。store.mode
store.lock.mode
store.session.mode
这三个值为db
,才能让seata连接到下面的数据库中。store.db
配置项下的配置,连接到自己的数据库。seata/script/config-center/config.txt
数据库的名称
与上述3.2
seata配置文件中的store.db.url
保持一致。
在上述库中添加seata的配置表,sql文件存放在:seata/script/server/db/mysql.sql
中
-- -------------------------------- The script used when storeMode is 'db' -------------------------------- -- the table to store GlobalSession data CREATE TABLE IF NOT EXISTS `global_table` ( `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `status` TINYINT NOT NULL, `application_id` VARCHAR(32), `transaction_service_group` VARCHAR(32), `transaction_name` VARCHAR(128), `timeout` INT, `begin_time` BIGINT, `application_data` VARCHAR(2000), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`xid`), KEY `idx_status_gmt_modified` (`status` , `gmt_modified`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- the table to store BranchSession data CREATE TABLE IF NOT EXISTS `branch_table` ( `branch_id` BIGINT NOT NULL, `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `resource_group_id` VARCHAR(32), `resource_id` VARCHAR(256), `branch_type` VARCHAR(8), `status` TINYINT, `client_id` VARCHAR(64), `application_data` VARCHAR(2000), `gmt_create` DATETIME(6), `gmt_modified` DATETIME(6), PRIMARY KEY (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(128), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking', `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_status` (`status`), KEY `idx_branch_id` (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; CREATE TABLE IF NOT EXISTS `distributed_lock` ( `lock_key` CHAR(20) NOT NULL, `lock_value` VARCHAR(20) NOT NULL, `expire` BIGINT, primary key (`lock_key`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0); INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0); INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0); INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);
-- 注意此处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 的 /bin 目录下 :/seata/bin 执行下面的脚本
sh seata-server.sh -p 8091 -h 127.0.0.1
参数解释:
-h: 将地址暴露给注册中心,其他服务可以访问seata服务器
-p:要侦听的端口
启动成功后,即可访问 http://127.0.0.1:7091/#/login 改地址进入seata的webui,用户名与密码默认为seata
,可在上面的1.2章节中中提到的application.yml
配置项:console.user
中修改
并且查看nacos
中的服务注册中心是否可以看到seata-server
至此,seater-server的配置与部署完成
<!-- 注意一定要引入对版本,要引入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>
配置文件中加入以下配置
seata:
tx-service-group: mygroup # 事务分组名称,要和服务端对应
service:
vgroup-mapping:
mygroup: default # key是事务分组名称 value要和服务端的机房名称保持一致
其中tx-service-group
配置项要与 上述2.3章节中提到的service.vgroupMapping.mygroup=default
中的group保持一致,
seata.service.vgroup-mapping.mygroup
中的mygroup
同理。
我们自己的服务要与seata-server
服务在同一个namespace
下
查看服务是否启动成功
查看nacos的对应的namespace中服务是否注册成功
在外层接口上增加@GlobalTransactional
注解
@GetMapping("/remoteTest")
@GlobalTransactional
public String remoteTest(){
orderService.remoteTest();
return "order success";
}
只需要在最外层方法上添加注解即可,子事务方法上不需要添加@GlobalTransactional
与@Transactional
注解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。