上篇文章介绍了分布式事务的解决方案,链接:
分布式事务,及基于Seata解决分布式事务_Alex-HH的博客-CSDN博客
这期讲讲Seata的安装与使用
https://github.com/seata/seata/releases
下载完成之后解压安装包
[root@localhost upload]# tar -zxvf seata-server-1.4.2.tar.gz -C /usr/local
随后修改seata/seata-server-1.4.2/conf/
目录下的registry.conf
文件:
registry {
#tc服务的注册中心类型,这里选择nacos,也可以是eureka、zookeeper等
type = "nacos"nacos {
# seata tc服务注册到nacos的服务名称,可以自定义
application = "seata-server"
# nacos的地址
serverAddr = "192.168.204.129:8848"
# seata服务所在分组
group = "DEFAULT_GROUP"
# seata服务所在的名称空间,这里不填就是使用默认的"public"
namespace = ""
# TC集群名,默认是"default"
cluster = "default"
# 这个是nacos的用户名
username = ""
# 这个是nacos的密码
password = ""
}
}
config {
# tc服务的配置中心类型:file、nacos 、apollo、zk、consul、etcd3
type = "nacos"nacos {
serverAddr = "192.168.204.129:8848"
namespace = ""
group = "DEFAULT_GROUP"
username = ""
password = ""
dataId = "seataServer.properties"
}
}
需要在Nacos中添加配置信息:
配置信息地址:script/config-center/config.txt · Seata/seata - Gitee.com
详情如下:
# 数据存储方式,db代表数据库
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://192.168.40.150:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=1111
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
# 事务、日志等配置
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.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none
# 关闭metrics功能,提高性能
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
效果如下:
创建TC服务数据表
- 建库 创建seata的数据库
- 建表 阿里已经提供好了相关的建表语句
建表语句地址:script/server/db/mysql.sql · Seata/seata - Gitee.com
undo_log建表语句:script/client/at/db/mysql.sql · Seata/seata - Gitee.com
建表语句如下:
-- -------------- 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;-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT 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
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
启动seata
在seata的bin目录下启动seata-server.sh
[root@localhost bin]# ./seata-server.sh
#或
[root@localhost bin]# ./seata-server.sh -h 192.168.204.135 -p 8091 #指定地址和端口号
出现以下内容则启动成功
... ...
io.seata.config.FileConfiguration : The configuration file used is /usr/local/seata/seata-server-1.4.2/conf/registry.conf
com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
i.s.core.rpc.netty.NettyServerBootstrap : Server started, listen port: 8091
在nacos的管理界面测试seata是否启动成功
导入相关依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
要查找TC服务,需要四个信息:namespace、group、application name、cluster name
如下图所示:
所以在application.yml配置文件中,我们需要给seata提供这些数据
seata:
registry:
type: nacos #查找TC服务,参考registry.conf
nacos:
server-addr: 192.168.204.129:8848
namespace: ""
group: DEFAULT_GROUP
application: seata-server #TC服务名
tx-service-group: seata-demo #事务组,根据tx-service-group名称获得TC服务cluster名称
service:
vgroup-mapping: #tx-service-group与TC cluster的映射关系
seata-demo: default
注意,这里启动服务的时候可能会存在RM注册失败,需要查看注册到nacos中的seata-server服务ip是否为公网ip,如果不是的话,在启动seata时要通过指定ip和端口的方式启动
剩下的使用就很简单了,通过seata提供的@GlobalTransactional注解替换Spring MVC的@Transactional注解,@GlobalTransactional标注的方法为全局事务的方法入口,seata会自动为我们进行事务控制。