不了解分布式事务的 看上篇文章点击这里
Seata集成Spring Cloud实战
Seata须知
下面进入实战,环境: springBoot2.2.2 + springCloud Hoxton.SR1 + seata1.2.0 + Mysql5.7
首先我们要明白seata中的几个术语:
我们来想象一个场景,现在有一个微服务架构的电商系统,其中包含了订单服务、库存服务
他们分别部署在不同的服务器上,连接的也是不同的数据库。(以下的操作不考虑复杂情况)
现在用户对商品进行购买操作,我们要做两件事:
我们可以想到,订单项目和库存项目 每一个都是RM(资源管理器)
因为他们驱动着自己本地的分支事务提交或者回滚
如图:
·
那么TM是谁?
如果我们还有一个服务 用来专门处理业务,这个服务中会调用 订单服务,库存服务。那么他就应该是TM
因为这个业务服务,需要开始全局事务。
那么谁又是TC(事务协调者)
其实就是Seata服务。那么一会我们会开启seata服务。他就是TC
Seata与SpringBoot、Cloud集成
1. 下载seata1.2.0
2. 创建数据库
这里注意:我们需要创建什么 这里的sql我会在后边粘贴,现在只需要知道创建什么即可。
a.创建单独的数据库(数据库名随意),用来记录分支信息等等
b.在每个业务数据库中都要创建undo_log表(用于记录回滚操作的)
如图:订单服务连接distribute_order数据库,则需要创建一张undo_log , 库存服务连接的是distribute_store 也是如此
- 编写order订单服务,store库存服务
编写过程略,我们只需要知道对数据库进行了什么操作即可
订单服务:连接distribute_order库,会插入一条记录进order表。
库存服务:连接distribute_store库,会根据购买的商品id,针对商品进行库存削减。
这里只贴出关键代码:
订单服务:
<mapper namespace="com.hzyc.springcloud.mapper.OrderMapper">
<insert id="insert" parameterType="Order">
insert into `order`(onum) values (#{
onum})
</insert>
</mapper>
库存服务:
<mapper namespace="com.hzyc.springcloud.mapper.GoodMapper">
<update id="update" parameterType="int">
update good set count = count - 1 where id = #{
id}
</update>
</mapper>
3.修改seata-server配置【重要】
3.1找到registry.conf并修改
我们都知道微服务是有注册中心的(注册中心不懂说明不会微服务…),我们现在需要把seata服务注册到中心中
注册中心我用的是eureka,如图
所以我们修改registry.conf 主要就是type=“eureka” , 以及eureka的地址别写错了。
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "eureka"
nacos {
application = "seata-server"
serverAddr = "localhost"
namespace = ""
cluster = "default"
username = ""
password = ""
}
eureka {
serviceUrl = "http://localhost:8761/eureka/"
application = "seata-server"
weight = "1"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
file {
name = "file.conf"
}
}
3.2 修改file.conf
这个文件主要是配置seata-server连接的数据库,还记得我们在第二步创建的数据库吗
这里主要就是配置service模块 、和下面的db模块
#这里手动加入service模块
service {
#transaction service group mapping
#修改,可不改,my_test_tx_group随便起名字。
vgroup_mapping.my_test_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
# 此服务的地址
default.grouplist = "127.0.0.1:8091"
#disable seata
disableGlobalTransaction = false
}
## transaction log store, only used in seata-server
store {
## store mode: file、db
mode = "db"
## 数据库连接的位置 重要
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/seata"
user = "root"
password = "mysql"
minConn = 5
maxConn = 30
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
4.修改项目文件集成seata功能
这一步主要是让我们的order服务,store服务、以及我们的业务服务。能够使用分布式事务
4.1修改pom文件 加入seata依赖
只要涉及分布式事务的项目,都加上 ! !
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
4.2修改项目配置文件
这里大家可以修改properties文件/yml配置文件。加入以下的配置,当然yml和properties写法有些区别这里不多赘述。大家都懂
##############################[seata配置]###################################################
#是否使用分布式事物
seata:
enabled: true
application-id: seata-bus
tx-service-group: my_test_tx_group
enable-auto-data-source-proxy: true
service:
vgroup-mapping.my_test_tx_group: default
grouplist.default: localhost:8091
##############################[seata配置]###################################################
5.开启分布式事务
使用注解@GlobalTransactional
这里调用了库存服务,又调用了订单服务
这是service业务层:
@GlobalTransactional
public String testGlobalTx(){
System.out.println("事务XID="+RootContext.getXID());
String url2 = "http://seata-store/update?id=1";
String result2 = restTemplate.getForObject