seata 分布式事务,举个栗子:A操作完自己的数据库又要同步B去 操作B自己的数据库, 这种跨应用的操作,可能出现数据不一致的问题。
直接上傻瓜式教程。 此文章没有使用配置中心。 如果使用配置中心的话,直接将配置的东西搬走就行了。问题不是很大。
seata 官网文档: http://seata.io/zh-cn/docs/overview/what-is-seata.html
seata 服务器资源下载:http://seata.io/zh-cn/blog/download.html
因为是github, 所以下载起来可能慢。这里推荐一个工具,fastgithub。 有时候速度很快,有时候又感觉不得劲。讲究用吧,实在不行就百度云盘去搜版本,然后下载吧
涉及依赖版本:
spring cloud version: Hoxton.SR10
spring cloud ali baba version: 2.2.3
mysql: 8.x
seata : 1.4.2
spring boot: 2.3.9
文章最后上我自己写的代码 git 地址。
Seata 服务器的配置 (本文使用AT模式)
下载解压缩下来之后。
- 进入conf文件目录下面,直接修改file.conf 文件
transport {
type = "TCP"
server = "NIO"
heartbeat = true
enableClientBatchSendRequest = false
enableRmClientBatchSendRequest = true
enableTcServerBatchSendResponse = false
rpcRmRequestTimeout = 30000
rpcTmRequestTimeout = 30000
rpcTcRequestTimeout = 30000
threadFactory {
bossThreadPrefix = "NettyBoss"
workerThreadPrefix = "NettyServerNIOWorker"
serverExecutorThreadPrefix = "NettyServerBizHandler"
shareBossWorker = false
clientSelectorThreadPrefix = "NettyClientSelector"
clientSelectorThreadSize = 1
clientWorkerThreadPrefix = "NettyClientWorkerThread"
bossThreadSize = 1
workerThreadSize = "default"
}
shutdown {
wait = 3
}
serialization = "seata"
compressor = "none"
}
store {
mode = "db"
publicKey = ""
db {
datasource = "druid"
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=GMT%2B8"
user = "root"
password = "admin"
minConn = 5
maxConn = 100
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
server {
recovery {
committingRetryPeriod = 1000
asynCommittingRetryPeriod = 1000
rollbackingRetryPeriod = 1000
timeoutRetryPeriod = 1000
}
undo {
logSaveDays = 7
logDeletePeriod = 86400000
}
vgroupMapping {
default_tx_group = default
}
maxCommitRetryTimeout = "-1"
maxRollbackRetryTimeout = "-1"
rollbackRetryTimeoutUnlockEnable = false
retryDeadThreshold = 130000
distributedLockExpireTime = 10000
enableParallelRequestHandle = false
xaerNotaRetryTimeout = 60000
session {
branchAsyncQueueSize = 5000
enableBranchAsyncRemove = false
}
}
log {
exceptionRate = 100
}
metrics {
enabled = false
registryType = "compact"
exporterList = "prometheus"
exporterPrometheusPort = 9898
}
- 修改registry.conf 文件,因为没有用到注册中心,所以这块只简单配置了eureka。 如果需要配置配置中心,直接根据下载出来的包里面的内容自行添加即可。
registry {
type = "eureka"
eureka {
serviceUrl = "http://localhost:9000/eureka"
application = "seata-server"
weight = "1"
}
}
- 启动自己的eureka 服务,然后去到bin 目录,当前目录打开cmd 窗口,然后执行 seata-server.bat 文件。CMD 窗口的命令直接输入文件的名字然后直接回车,就自己启动了。
启动的时候需要注意的问题:
mysql: 注意启动的时候需要将lib 目录下面的mysql 驱动复制一份到lib 目录下面,同时在file 文件配置的jdbc的时候, url = “jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=GMT%2B8” 需要加上servertimezone 时区的问题。
使用oracle 的时候需要注意: 需要将你工程目录里面使用的驱动直接粘贴jar包到lib目录下面。其余配置没有多余变化。
Seata 应用对于数据库表的依赖
服务包下载下来先不要急于配置了。该看的都得看。readme 打开里面的东西就很丰盛了。所有的server端, client端,配置中心的东西讲的很清楚。缺啥里面都有。
在使用seata 的时候,首先需要创建三张seata自身需要的表,具体查看file.conf 文件的store 的配置部分。
db {
datasource = “druid”
dbType = “mysql”
driverClassName = “com.mysql.jdbc.Driver”
url = “jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=GMT%2B8”
user = “root”
password = “admin”
minConn = 5
maxConn = 100
globalTable = “global_table”
branchTable = “branch_table”
lockTable = “lock_table”
queryLimit = 100
maxWait = 5000
}
三张表:global_table,branch_table,lock_table
然后从readme里面的内容:
# 脚本说明
## [client](https://github.com/seata/seata/tree/develop/script/client)
> 存放用于客户端的配置和SQL
- at: AT模式下的 `undo_log` 建表语句
- conf: 客户端的配置文件
- saga: SAGA 模式下所需表的建表语句
- spring: SpringBoot 应用支持的配置文件
## [server](https://github.com/seata/seata/tree/develop/script/server)
> 存放server侧所需SQL和部署脚本
- db: server 侧的保存模式为 `db` 时所需表的建表语句
- docker-compose: server 侧通过 docker-compose 部署的脚本
- helm: server 侧通过 Helm 部署的脚本
- kubernetes: server 侧通过 Kubernetes 部署的脚本
## [config-center](https://github.com/seata/seata/tree/develop/script/config-center)
> 用于存放各种配置中心的初始化脚本,执行时都会读取 `config.txt`配置文件,并写入配置中心
- nacos: 用于向 Nacos 中添加配置
- zk: 用于向 Zookeeper 中添加配置,脚本依赖 Zookeeper 的相关脚本,需要手动下载;ZooKeeper相关的配置可以写在 `zk-params.txt` 中,也可以在执行的时候输入
- apollo: 向 Apollo 中添加配置,Apollo 的地址端口等可以写在 `apollo-params.txt`,也可以在执行的时候输入
- etcd3: 用于向 Etcd3 中添加配置
- consul: 用于向 consul 中添加配置
server 端直接进它的git,里面就有存放三张表的sql 脚本,直接执行创建。在这不写了。
另外client 端的undo_log 表,也在这里。这个主要放在那里呢? 当然是你当前需要进行分布式事务控制的数据库。
到这里Seata 的服务器部分配置就已经结束了。
应用代码层面
吐槽一下,配置项目真的是多,好多根本不知道啥意思。留着以后继续精进学习吧。
官网参数介绍:http://seata.io/zh-cn/docs/user/configurations.html
下面为seata 在应用配置文件中的配置:
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: default_tx_group
access-key: aliyunAccessKey
secret-key: aliyunSecretKey
enable-auto-data-source-proxy: true
data-source-proxy-mode: AT
use-jdk-proxy: false
scan-packages: firstPackage,secondPackage
excludes-for-scanning: firstBeanNameForExclude,secondBeanNameForExclude
excludes-for-auto-proxying: firstClassNameForExclude,secondClassNameForExclude
client:
rm:
async-commit-buffer-limit: 10000
report-retry-count: 5
table-meta-check-enable: false
report-success-enable: false
saga-branch-register-enable: false
saga-json-parser: fastjson
saga-retry-persist-mode-update: false
saga-compensate-persist-mode-update: false
tcc-action-interceptor-order: -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
sql-parser-type: druid
lock:
retry-interval: 10
retry-times: 30
retry-policy-branch-rollback-on-conflict: true
tm:
commit-retry-count: 5
rollback-retry-count: 5
default-global-transaction-timeout: 60000
degrade-check: false
degrade-check-period: 2000
degrade-check-allow-times: 10
interceptor-order: -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
undo:
data-validation: true
log-serialization: jackson
log-table: undo_log
only-care-update-columns: true
compress:
enable: true
type: zip
threshold: 64k
load-balance:
type: XID
virtual-nodes: 10
service:
vgroup-mapping:
default_tx_group: seata-server
grouplist:
default: 127.0.0.1:8091
enable-degrade: false
disable-global-transaction: false
transport:
shutdown:
wait: 3
thread-factory:
boss-thread-prefix: NettyBoss
worker-thread-prefix: NettyServerNIOWorker
server-executor-thread-prefix: NettyServerBizHandler
share-boss-worker: false
client-selector-thread-prefix: NettyClientSelector
client-selector-thread-size: 1
client-worker-thread-prefix: NettyClientWorkerThread
worker-thread-size: default
boss-thread-size: 1
type: TCP
server: NIO
heartbeat: true
serialization: seata
compressor: none
enable-tm-client-batch-send-request: false
enable-rm-client-batch-send-request: true
rpc-rm-request-timeout: 15000
rpc-tm-request-timeout: 30000
registry:
type: eureka
eureka:
weight: 1
service-url: http://localhost:9000/eureka
log:
exception-rate: 100
顺便说一句,这块里面有个需要注意的点。因为上述配置也是直接从readme 里面找到并且直接粘贴复制过来的,然后小改了几个配置,如下:
application-id: ${spring.application.name}
service:
vgroup-mapping:
default_tx_group: seata-server
第二个配置的时候切记需要和seata 服务器的eureka 里面的配置信息一定要一致。
如果不一致,可能导致找不到seata 的服务器
代码就更简单了。 只需要在你想要的进行事务控制的地方使用下面那个注解就可以了。
@GlobalTransactional(rollbackFor = Exception.class)
调用方:
被调方:
执行结果:
查询数据库,数据库的数据确实没有任何问题。
这块对网上的文章有几个疑惑,根据我这一天的学习时间,也不敢妄下定论:
- 网上说的调用方和被调用方都需要加seata 的配置? 目前我实验的结果是只需要调用方加上seata 的配置就可以了。
- 关于undo_log 的表,网上说调用方和被调用方的数据库都需要创建? 目前我实验的结果还是只需要在调用方加上就可以了。
因为学习时间短,没有进行系统,正式的学习。都是直接参考网上的文章,官方文档进行快速应用。好多只是停留在刚会用的地步,等日后精进了,在回来补偿这两个问题。
最后附上git代码: https://github.com/tsl1234/seata_demo.git