前言:
- 需要注意seata版本依赖,不然版本冲突和jar包冲突会一直报错,建议先配置成功再慢慢调整自己喜欢的版本,
- 这里使用的是seata:1.3.0 nacos:1.3.0
- 默认会使用docker基础操作
1. docker启动nacos
docker run -e MODE=standalone --name nacos-server -p 8848:8848 -d nacos/nacos- server:1.3.0
2. docker 启动seata
2. docker 启动seatadocker run -e MODE=standalone --name nacos-server -p 8848:8848 -d nacos/nacos- server:1.3.0
docker启动seata ,这里我提前复制过一份seata配置目录,启动的时候直接挂载本地目录。
-e SEATA_IP=192.168.209.134 指定seata所在IP地址写你自己的
-e SEATA_PORT=8091 seata端口
3 . 配置seata配置文件registry.confdocker run -d --name seata -p 8091:8091 -v /seata-server:/seata-server -e SEATA_IP=192.168.209.134 -e SEATA_PORT=8091 seataio/seata-server:1.3.0
只需要修改nacos部分和config部分,按照自己的进行修改,其他不需要动。 补充一句:不要修改同目录下的file.config文件,后面会使用官方给的脚本上传数据库配置和事务组到nacos。
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos" #选择nacos
nacos {
application = "seata-server" #注册进nacos服务名 默认
serverAddr = "192.168.209.134:8848" #nacos IP地址
group = "SEATA_GROUP" # 默认的 分组
namespace = "73ed2a03-9f59-4148-b06f-1cf605bb637c" #注册上nacos的命名空间默认是public 建议在nacos创建一个命名空间
cluster = "default" #默认default
username = "nacos" #nacos 用户名
password = "nacos" #nacos 密码
}
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos" #选择nacos
nacos {
serverAddr = "192.168.209.134:8848" #nacosIP地址
namespace = "73ed2a03-9f59-4148-b06f-1cf605bb637c" #nacos命名空间
group = "SEATA_GROUP" #默认分组
username = "nacos" #nacos 用户名
password = "nacos" #nacos 密码
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
appId = "seata-server"
apolloMeta = "http://192.168.1.204:8801"
namespace = "application"
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
4. 创建config.txt
随便创建一个文件夹,里面创建一个config.txt。后面带注解的就是需要你要去配置的,内容如下
5. 编写 nacos-config.sh 脚本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.vgroup_mapping.order-service-seata-service-group=default service.vgroup_mapping.account-service-seata-service-group=default service.vgroup_mapping.stock-service-seata-service-group=default service.vgroup_mapping.business-service-seata-service-group=default service.vgroupMapping.fsp_tx_group=default #这里是创建自己的事务分组使用驼峰命名,后面配置yml要用到,上面4个是官方给的,知道即可 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 store.mode=db #修改db 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.driver-class-name=com.mysql.jdbc.Driver store.db.datasource=druid #数据源druid store.db.db-type=mysql store.db.url=jdbc:mysql://IP:3306/seata?useUnicode=true #这里的seata数据库是一会要创建的,照写 store.db.user=root #数据库用户名 store.db.password=456789 #数据库密码 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 client.report.retry.count=5 service.disableGlobalTransaction=false client.support.spring.datasource.autoproxy=true
在当前文件存放 config.txt 目录下再新建一个文件夹,文件夹里新建nacos-config.sh 内容如下
#!/usr/bin/env bash
# Copyright 1999-2019 Seata.io Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at、
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
while getopts ":h:p:g:t:u:w:" opt
do
case $opt in
h)
host=$OPTARG
;;
p)
port=$OPTARG
;;
g)
group=$OPTARG
;;
t)
tenant=$OPTARG
;;
u)
username=$OPTARG
;;
w)
password=$OPTARG
;;
?)
echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
exit 1
;;
esac
done
if [[ -z ${host} ]]; then
host=localhost
fi
if [[ -z ${port} ]]; then
port=8848
fi
if [[ -z ${group} ]]; then
group="SEATA_GROUP"
fi
if [[ -z ${tenant} ]]; then
tenant=""
fi
if [[ -z ${username} ]]; then
username=""
fi
if [[ -z ${password} ]]; then
password=""
fi
nacosAddr=$host:$port
contentType="content-type:application/json;charset=UTF-8"
echo "set nacosAddr=$nacosAddr"
echo "set group=$group"
failCount=0
tempLog=$(mktemp -u)
function addConfig() {
curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$1&group=$group&content=$2&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
if [[ -z $(cat "${tempLog}") ]]; then
echo " Please check the cluster status. "
exit 1
fi
if [[ $(cat "${tempLog}") =~ "true" ]]; then
echo "Set $1=$2 successfully "
else
echo "Set $1=$2 failure "
(( failCount++ ))
fi
}
count=0 #读取上一级文件夹里面的config.txt 文件
for line in $(cat $(dirname "$PWD")/config.txt | sed s/[[:space:]]//g); do
(( count++ ))
key=${line%%=*}
value=${line#*=}
addConfig "${key}" "${value}"
done
echo "========================================================================="
echo " Complete initialization parameters, total-count:$count , failure-count:$failCount "
echo "========================================================================="
if [[ ${failCount} -eq 0 ]]; then
echo " Init nacos config finished, please start seata-server. "
else
echo " init nacos config fail. "
fi
6. 执行脚本推送到nacos上
对应nacos的 -h IP -p端口 -g分组(要和前面配置一样,不要修改) -t 命名空间
sh nacos-config.sh -h 192.168.209.134 -p 8848 -g SEATA_GROUP -t 73ed2a03-9f59-4148-b06f-1cf605bb637c
docker restart seata 然后重启seata7. 创建seata数据库执行以下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_gmt_modified_status` (`gmt_modified`, `status`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; -- 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 = utf8; -- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAr(128) NOT NULL, `xid` VARCHAr(96), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAr(256), `table_name` VARCHAr(32), `pk` VARCHAr(36), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;8. 添加undo_log表
自己每个业务的数据库要增加一张undo_log表,内容如下
-- 注意此处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;9. 父POM版本依赖
10. 子项目依赖org.springframework.boot spring-boot-dependencies2.2.5.RELEASE pom import org.springframework.cloud spring-cloud-dependenciesHoxton.SR3 pom import com.alibaba.cloud spring-cloud-alibaba-dependencies2.2.1.RELEASE pom import
依赖版本最好不要改动了,不要引入druid的依赖,seata-spring-boot-starter里面自带了,自己引入会jar包冲突报错。
11. 微服务yml配置org.springframework.boot spring-boot-starter-testtest org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-actuatorcom.baomidou mybatis-plus-boot-starter3.4.2 org.springframework.cloud spring-cloud-starter-openfeignmysql mysql-connector-java8.0.28 runtime com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discoveryorg.projectlombok lombok1.18.20 io.seata seata-spring-boot-starter1.3.0 com.alibaba.cloud spring-cloud-starter-alibaba-seataio.seata seata-spring-boot-starter
server:
port: 2001
spring:
application:
name: seata-order-service
cloud:
nacos:
discovery:
server-addr: 192.168.209.134:8848
namespace: 73ed2a03-9f59-4148-b06f-1cf605bb637c
group: SEATA_GROUP
datasource:
url: jdbc:mysql://127.0.0.1:3306/seata_account?characterEncoding=utf8&useSSL=false
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
password: 456789
management:
endpoints:
web:
exposure:
include: '*'
mybatis-plus:
mapperLocations: classpath:mapper/*.xml
#----------------------上面的配置就不说了,根据自己的配 配datasource 的时候不要加druid,写上会报错---------------------------------------------------------
seata:
enabled: true # 1.0新特性,需要依赖seata-spring-boot-starter 默认为true
enable-auto-data-source-proxy: true # 开启seata数据源代理
tx-service-group: fsp_tx_group # 需要与config.txt中的 service.vgroupMapping.seata_test_group=default保持一致
service:
vgroup-mapping:
fsp_tx_group: default #需要与config.txt中的 service.vgroupMapping.seata_test_group=default 保持一致
disable-global-transaction: false
registry: # 注册中心 与register.conf文件中的保持一致
type: nacos #注册nacos
nacos:
application: seata-server #nacos中seata-server启动注册成功后的服务名称
serverAddr: 192.168.209.134:8848
username: nacos
password: nacos
namespace: 73ed2a03-9f59-4148-b06f-1cf605bb637c
group: SEATA_GROUP
config: ## 配置中心 与register.conf文件中的保持一致
type: nacos
nacos:
serverAddr: 192.168.209.134:8848
username: nacos
password: nacos
namespace: 73ed2a03-9f59-4148-b06f-1cf605bb637c
group: SEATA_GROUP
application-id: ${spring.application.name}
12. 最后
只要在方法上加上注解@GlobalTransactional(rollbackFor = Exception.class) 即可
提醒
- 不需要自己去写一个数据源代理,这种配置自动开启数据源代理
- 不要去启动类排除DataSourceAutoConfiguration.class,
- 启动类不要加@Mapperscan注解



