Springboot+nacos+seata实现简单的分布式事务
*书接上回,上一篇文章搭建的nacos注册中心,本次要把seata服务和三个springboot服务集成进去
seata集成nacos
- 下载seata,下载地址: https://github.com/seata/seata/releases
这里我下载的是1.6.1的版本
选择这个压缩包,下载好解压后我们还要修改一下配置文件。
在修改配置文件之前我们还需要在nacos管理页面进行配置
在左侧菜单栏选择命名空间,然后新建命名空间,当然你也可以不用自己新建,可以用默认的public。我这里为了区分,创建了名为seata的空间
好了,我们开始需改seata的配置文件。
首先:打开conf目录下的application.yml和application.example.yml文件。刚解压的application.yml文件里面配置都是空的,需要application.example.yml文件里提供的模板。
第一步:修改以上seata服务的注册方式和配置方式,各参数详情如下图:
第二步:修改存储模式配置文件,这里我用的db模式,在 db 模式下,我们需要针对全局事务的会话信息创建以下 3 张数据库表。
1:全局事务表,对应的表为:global_table
2:分支事务表,对应的表为:branch_table
3:全局锁表,对应的表为:lock_table
global_table
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;
branch_table
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;
lock_table
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;
第三步:启动bin目录下的seata-server.bat,出现下图所示就代表启动成功了
接着我们去nacos查看
seata服务已经注册进去了。好了,接下来我们要创建三个服务了
在这里我用idea创建了三个服务:
打开springdemoOrder项目先引入依赖包,我这创建了三个服务,使用openfeign实现相互调用,所要导入的包有:openfeign相关的依赖包,mysql依赖包,seata依赖包,nacos相关依赖包
openfeign相关的依赖包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
mysql依赖包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
seata依赖包
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.6.1</version>
</dependency>
nacos相关依赖包
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.1.RELEASE</version>
<exclusions>
<!-- 将ribbon排除 -->
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
nacos的依赖中,我把ribbon排除,至于为什么排除到后面出错的时候说一下。三个服务都用上面的依赖
依赖导入完成我们要创建配置文件了,创建application.yml文件,我的配置文件如下:
server:
port: 8080
spring:
application:
name: seataOrder #服务名
# main:
# allow-bean-definition-overriding: true
datasource:
driver-class-name: com.mysql.jdbc.Driver #数据库驱动
url: jdbc:mysql://xxxxxx/xxx?characterEncoding=utf-8&serverTimeZone=GMT%2B8&useSSL=false
username: xxx
password: xxx
cloud:
nacos:
discovery:
ip: 127.0.0.1:8080
autoRegister: true
server-addr: 127.0.0.1:8848 #nacos 服务器地址
namespace: seata #nacos 命名空间
username: nacos
password: nacos
group: SEATA_GROUP
config:
username: nacos
password: nacos
context-path: /nacos
server-addr: 127.0.0.1:8848 # 设置配置中心服务端地址
namespace: seata
alibaba:
seata:
#自定义服务群组,该值必须与 Nacos 配置中的 service.vgroupMapping.{my-service-group}=default 中的 {my-service-group}相同
tx-service-group: order
seata:
application-id: ${spring.application.name}
tx-service-group: order
# enable-auto-data-source-proxy: false
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848 # Nacos 注册中心的地址
group: "SEATA_GROUP" #分组,这里和配置文件里的一样
namespace: "seata" # Nacos 注册中心的配置ID
username: "nacos" # Nacos 注册中心的用户名
password: "nacos" # Nacos 注册中心的密码
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: "seata"
group: SEATA_GROUP
username: "nacos"
password: "nacos"
service:
vgroup-mapping:
my_test_tx_group: default
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details=always:
feign:
sentinel:
enabled: true #开启 OpenFeign 功能
配置完成后启动一下试试,看看效果
已经注册进nacos里了,看看seata服务的订阅者下有没有order服务,结果如下图
启动另外两个服务,配置文件和上面的一样,不过下面这两个参数需要修改
修改完后启动另外两个服务,如出现下图红框的标识就代表三个都注册进去了
然后打开seata订阅者列表看看
结果发现只有一个订阅者,应用名为unknow,着没道理啊,后来我在每个服务的启动参数里加上了:-Dproject.name =xxx就行了
再次启动发现正常,应该是没有
我猜测大概是三个服务都应用名都是一样的就会发生覆盖。这篇就先这样了,下一篇在写业务代码