目录
一、简介
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
1、版本选择
https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明
2、seata版本
- 本例使用的是seata:1.3.0
3、注册中心
- 本例使用nacos作为seata的注册中心和配置中心
二、新建seata数据库
- 新建数据库,名称叫rapid_seata
- schema地址 https://github.com/seata/seata/blob/1.3.0/script/server/db/mysql.sql
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;
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;
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;
三、nacos配置
nacos的安装请参考我的另一篇文章:https://www.cnblogs.com/lvlinguang/p/15719224.html
1、新建命名空间
- 命名空间名称:seata
- 得到的命名空间ID:f01f8dbd-43a4-4500-84f8-b0041d4d0cbe
2、将seata配置信息推送至nacos
2.1、下载1.3.0的源码
2.2、修改/替换config.txt里的内容,如下
- config.txt文件路径:\script\config-center\config.txt
- 事务分组rapid_cloud_tx_group,这个是可以自定义修改的,该配置需要与项目中的事务分组配置保持一致
service.vgroupMapping.rapid_cloud_tx_group=default
# service.vgroupMapping.test_tx_group=default
# service.vgroupMapping.prod_tx_group=default
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:8848/rapid_seata?useUnicode=true
store.db.user=root
store.db.password=123456
2.3、将配置信息推送至nacos
- nacos-config.sh文件路径:\script\config-center\nacos
- 在地址栏输入cmd并回车
nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t b6e82b1b-176a-45d0-8c8c-701bdfc2e8a2
-
参数描述:
- -h: host, 默认值 localhost
- -p: port, 默认值 8848
- -g: 配置分组 默认值 SEATA_GROUP
- -t: 命名空间
- -u: 用户名, nacos 1.2.0+ 之后添加权限验证 默认为''
- -w: 密码, nacos 1.2.0+ 之后添加权限验证 默认为''
-
推送成功后如下图
四、seata安装
1、docker方式安装
1、拉取镜像
docker pull seataio/seata-server:1.3.0
2、新建目录
mkdir -p /home/apps/seata/config
# 进入目录
cd /home/apps/seata/config
3、新建registry.conf
# 注册中心
registry {
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = "f01f8dbd-43a4-4500-84f8-b0041d4d0cbe"
cluster = "default"
username = "nacos"
password = "nacos"
}
}
# 配置中心
config {
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = "f01f8dbd-43a4-4500-84f8-b0041d4d0cbe"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
}
4、创建并启动
- SEATA_IP:seata注册到nacos上的ip地址,测试环境建议用外网地址,这样本地程序也可以连接到seata,生产环境建议用内网地址/不配置此项,提升应用速度及安全性。
docker run \
-d \
--name seata-server \
--restart=always \
--privileged=true \
-p 8091:8091 \
-e SEATA_IP=127.0.0.1 \
-e SEATA_PORT=8091 \
-e SEATA_CONFIG_NAME=file:/root/seata-config/registry \
-v /home/apps/seata/config:/root/seata-config \
seataio/seata-server:1.3.0
2、k8s方式安装
apiVersion: v1
kind: Service
metadata:
name: seata-server
namespace: default
spec:
type: ClusterIP
selector:
k8s-app: seata-server
ports:
- name: http
port: 8091
targetPort: 8091
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: seata-server
namespace: default
labels:
k8s-app: seata-server
spec:
replicas: 1
selector:
matchLabels:
k8s-app: seata-server
template:
metadata:
labels:
k8s-app: seata-server
spec:
containers:
- name: seata-server
image: seataio/seata-server:1.3.0
imagePullPolicy: IfNotPresent
env:
- name: SEATA_CONFIG_NAME
value: file:/root/seata-config/registry
- name: SEATA_IP
value: "127.0.0.1"
ports:
- name: http
containerPort: 8091
hostPort: 8091
protocol: TCP
volumeMounts:
- name: seata-config
mountPath: /root/seata-config
volumes:
- name: seata-config
configMap:
name: seata-server-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: seata-server-config
namespace: default
data:
registry.conf: |
registry {
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = "f01f8dbd-43a4-4500-84f8-b0041d4d0cbe"
username = "nacos"
password = "nacos"
}
}
config {
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = "f01f8dbd-43a4-4500-84f8-b0041d4d0cbe"
username = "nacos"
password = "nacos"
}
}
五、springCloud中使用
1、pom文件配置
<properties>
<spring-cloud-alibaba.version>2.1.1.RELEASE</spring-cloud-alibaba.version>
<spring-boot.version>2.2.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
<seata-version>1.3.0</seata-version>
</properties>
<dependencies>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--spring cloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
<exclusions>
<exclusion>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
</exclusion>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<!--排除tomcat依赖-->
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--seata 分布式事务-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.1.4.RELEASE</version>
<exclusions>
<!--版本较低,因此排除-->
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>${seata-version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>${seata-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2、yml配置
seata:
enabled: true
tx-service-group: rapid_cloud_tx_group
service:
vgroup-mapping:
rapid_cloud_tx_group: default
registry:
type: nacos
nacos:
application: seata-server
server-addr: 192.168.3.12:8848
group: SEATA_GROUP
namespace: 'f01f8dbd-43a4-4500-84f8-b0041d4d0cbe'
username: 'nacos'
password: 'nacos'
config:
type: nacos
nacos:
server-addr: ${seata.registry.nacos.server-addr}
group: SEATA_GROUP
namespace: 'f01f8dbd-43a4-4500-84f8-b0041d4d0cbe'
username: 'nacos'
password: 'nacos'
3、@GlobalTransactional 添加注解开启事务
@RestController
@RequestMapping("/user")
public class UserController {
@GlobalTransactional
@GetMapping(value = {"/test-tx"})
public void txTest(Boolean rollBack) {
//修改项目信息
remoteProjectService.updateProject("1484aa83c695482a8dbcbe26cdfb6e6d", "测试事务修改");
//修改用户信息
userService.updateUserById("26ff71ec665b4557b4fe64ff1f7d469d", "事务修改");
}
}
4、源代码案例
六、参考
- https://blog.csdn.net/weixin_45103793/article/details/122982437
- https://blog.csdn.net/Main_1125/article/details/123709878
- https://zhuanlan.zhihu.com/p/443706623