https://blog.csdn.net/sinat_38670641/article/details/108237920
头痛于分布式事务的解决,找了一下相关的开源解决方案,主要有两个:
tx-lcn
seata
因为tx-lcn
好像没有解决资金问题,似乎有停止维护的趋势,所以本人选择了seata
。
然后在seata
整合SpringCloud
Nacos
的过程中踩了太多的坑,网上大多数博客使用版本都比较靠前,v1.0.0
起以后的版本压缩包中缺少部分执行文件
。所以想把自己踩过的坑写一下,希望能帮到有需要的同学,为大家节省一些时间。
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
官网:https://seata.io/zh-cn/
seata-server下载链接:https://github.com/seata/seata/releases/tag/v1.2.0
seata-server配置官方相关文档:https://github.com/seata/seata-samples/tree/master/springcloud-nacos-seata
官方demo:https://github.com/seata/seata-samples/tree/master
下载nacos
客户端:https://github.com/alibaba/nacos/releases
配置nacos
数据源
nacos-config
/conf/nacos-mysql.sql
/conf/application.properties
# 数据库类型
spring.datasource.platform=mysql
# 数据源数量
db.num=1
# 数据源1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
# 数据源2
#db.url.1=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
启动nacos
客户端
/bin/startup.cmd
/bin/startup.sh
nacos
控制台:http://127.0.0.1:8848/nacos/index.html#/login
nacos
nacos
修改conf/registry.conf
配置
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
# serverAddr 不需要带http://,配置nacos注册中心所以服务器ip,本人是本机启动的nacos
serverAddr = "127.0.0.1"
# nacos工作台中的命名空间,使用【public(保留空间)】即可
namespace = "public"
cluster = "default"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "127.0.0.1"
namespace = "public"
cluster = "default"
}
}
修改conf/file.conf
配置
store {
## store mode: file、db
# 修改为 db
mode = "db"
## file store property
file {
## store location dir
dir = "sessionStore"
# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
maxBranchSessionSize = 16384
# globe session size , if exceeded throws exceptions
maxGlobalSessionSize = 512
# file buffer size , if exceeded allocate new buffer
fileWriteBufferCacheSize = 16384
# when recover batch read size
sessionReloadReadSize = 100
# async, sync
flushDiskMode = async
}
## database store property
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
# 修改配置的数据库链接,数据库账号密码
url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC"
user = "root"
password = "root"
minConn = 5
maxConn = 30
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
配置seata
数据库,v1.0.0
以下版本提供conf/db_store.sql
脚本,v1.0.0(包括v1.0.0)
版本起压缩包不提供,此处大坑
。附上sql脚本
-- the table to store GlobalSession data
drop table if exists `global_table`;
create table `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_gmt_modified_status` (`gmt_modified`, `status`),
key `idx_transaction_id` (`transaction_id`)
);
-- the table to store BranchSession data
drop table if exists `branch_table`;
create table `branch_table` (
`branch_id` bigint not null,
`xid` varchar(128) not null,
`transaction_id` bigint ,
`resource_group_id` varchar(32),
`resource_id` varchar(256) ,
`lock_key` varchar(128) ,
`branch_type` varchar(8) ,
`status` tinyint,
`client_id` varchar(64),
`application_data` varchar(2000),
`gmt_create` datetime,
`gmt_modified` datetime,
primary key (`branch_id`),
key `idx_xid` (`xid`)
);
-- the table to store lock data
drop table if exists `lock_table`;
create table `lock_table` (
`row_key` varchar(128) not null,
`xid` varchar(96),
`transaction_id` long ,
`branch_id` long,
`resource_id` varchar(256) ,
`table_name` varchar(32) ,
`pk` varchar(36) ,
`gmt_create` datetime ,
`gmt_modified` datetime,
primary key(`row_key`)
);
修改conf/nacos-config.txt
配置,此处大坑
,同上,v1.0.0
以下版本提供该文件,v1.0.0(包括v1.0.0)
版本起压缩包不提供
附上nacos-config.txt
内容
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.thread-factory.boss-thread-prefix=NettyBoss
transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker
transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler
transport.thread-factory.share-boss-worker=false
transport.thread-factory.client-selector-thread-prefix=NettyClientSelector
transport.thread-factory.client-selector-thread-size=1
transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
transport.thread-factory.boss-thread-size=1
transport.thread-factory.worker-thread-size=8
transport.shutdown.wait=3
service.vgroupMapping.demo-server-group=default
service.vgroupMapping.demo2-server-group=default
service.enableDegrade=false
service.disable=false
service.max.commit.retry.timeout=-1
service.max.rollback.retry.timeout=-1
client.async.commit.buffer.limit=10000
client.lock.retry.internal=10
client.lock.retry.times=30
client.lock.retry.policy.branch-rollback-on-conflict=true
client.table.meta.check.enable=true
client.report.retry.count=5
client.tm.commit.retry.count=1
client.tm.rollback.retry.count=1
store.mode=file
store.file.dir=file_store/data
store.file.max-branch-session-size=16384
store.file.max-global-session-size=512
store.file.file-write-buffer-cache-size=16384
store.file.flush-disk-mode=async
store.file.session.reload.read_size=100
store.db.datasource=dbcp
store.db.db-type=mysql
store.db.driver-class-name=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC
store.db.user=root
store.db.password=root
store.db.min-conn=1
store.db.max-conn=3
store.db.global.table=global_table
store.db.branch.table=branch_table
store.db.query-limit=100
store.db.lock-table=lock_table
recovery.committing-retry-period=1000
recovery.asyn-committing-retry-period=1000
recovery.rollbacking-retry-period=1000
recovery.timeout-retry-period=1000
transaction.undo.data.validation=true
transaction.undo.log.serialization=jackson
transaction.undo.log.save.days=7
transaction.undo.log.delete.period=86400000
transaction.undo.log.table=undo_log
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registry-type=compact
metrics.exporter-list=prometheus
metrics.exporter-prometheus-port=9898
support.spring.datasource.autoproxy=false
此处请修改为您需要注册的服务的名称,我这里例子是demo-server-group
和demo2-server-group
PS:注意!!!!此处有坑,v1.1.0版本之下是vgroup_mapping,v1.1.0版本开始修改为vgroupMapping
,高版本没有修改够来会报no service ....
也可以从v0.9.0
版本的压缩包拉一份出来,但是,请务必注意!!!!
如果使用v1.1.0
起的版本记得把vgroup_mapping
修改为vgroupMapping
使用nacos-config.sh
同步配置到nacos
,此处有坑
,同上,v1.0.0
以下版本提供该文件,v1.0.0(包括v1.0.0)
版本起压缩包不提供
可以从v0.9.0
版本的压缩包拉一份出来
附上,也可以自行创建
#!/usr/bin/env bash
if [ $# != 1 ]; then
echo "./nacos-config.sh nacosIp"
exit -1
fi
nacosIp=$1
echo "set nacosIp=$nacosIp"
error=0
for line in $(cat nacos-config.txt)
do
key=${line%%=*}
value=${line#*=}
echo "\r\n set "${key}" = "${value}
result=`curl -X POST "http://$nacosIp:8848/nacos/v1/cs/configs?dataId=$key&group=SEATA_GROUP&content=$value"`
if [ "$result"x == "true"x ]; then
echo "\033[42;37m $result \033[0m"
else
echo "\033[41;37 $result \033[0m"
let error++
fi
done
if [ $error -eq 0 ]; then
echo "\r\n\033[42;37m init nacos config finished, please start seata-server. \033[0m"
else
echo "\r\n\033[41;33m init nacos config fail. \033[0m"
fi
执行命令, 后面填写nacos
的IP地址,我的是本机所以是127.0.0.1
sh nacos-config.sh 127.0.0.1
成功后会提示
init nacos config finished, please start seata-server
启动seata-server
bin/seata-server.bat
bin/seata-server.sh
启动成功nacos
服务列表可以查到seata-server
服务注册
相关jar包
com.alibaba.cloud
spring-cloud-alibaba-seata
2.1.0.RELEASE
io.seata
seata-all
1.2.0
版本说明:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明
在业务数据库添加undo_log
表,v1.0.0
以下提供conf/db_undo_log.sql
脚本文件,v1.0.0
版本起不提供,附上脚本
drop table `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;
配置代理数据源
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;
/**
* seata分布式事务代理数据源
* date:2020-4-30 13:12:33
*
* @author MrBUS
* @since JDK 1.8
* @version 1.0
*/
@Configuration
public class SeataConfiguration {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
@Primary
@Bean("dataSource")
public DataSourceProxy dataSource(DataSource druidDataSource){
return new DataSourceProxy(druidDataSource);
}
}
启动类开启自动注入:
@EnableDiscoveryClient
@EnableAutoConfiguration
配置文件application.yml
中配置:
spring:
cloud:
alibaba:
seata:
# nacos-config.txt中配置的service-vgroupMapping
tx-service-group: demo-server-group
在需要开启事务的最上层方法加上@GlobalTransactional(rollbackFor = Exception.class)
注解即可
以上仅代表个人理解,仅供参考。希望能帮助到有需要的同学。个人技术程度有限,有不对的地方望谅解。
v1.0.0
起缺少的文件已打包放在文章中,需要的同学可以免费下载。如果觉得本文有用,请点击一下点赞
或收藏
。谢谢。
https://download.csdn.net/download/sinat_38670641/12376400