项目技术
SpringCloudAlibaba Nacos Seata Mysql Feign
代码地址
这个代码我是基于 图灵学院 的项目改的, 原来的项目代码演示下单,扣库存,扣账户金额,一系列的业务代码,我感觉太臃肿了,其实分布式事务无外乎就是多个服务分别进行写操作多个mysql库,要么同时写入成功要么同时写入失败.
我把业务代码都删了,直接用最简单的方式演示多个微服务分别操作不同的数据库,要么同时insert成功,要么触发异常都不会写进数据,不会出现一个库insert进去数据,一个库没有insert进去数据的情况
代码地址:
https://gitee.com/zjj19941/ZJJ_Neaten5.10/tree/master/ZJJ_Seata/springcloud-nacos-feign-seata
代码说明
执行sql脚本
项目里面有个db.sql文件,自己自行创建两个数据库,然后根据下面图片去执行sql脚本, 在seata_storage库里面创建undo_log表和storage_tbl表, 在 seata_order库里面创建undo_log表和order_tbl表
registry.conf
registry {
type = "nacos"
nacos {
serverAddr = "zjj101:8848"
namespace = ""
cluster = ""
group = "SEATA_GROUP"
}
}
config {
type = "nacos"
nacos {
serverAddr = "zjj101:8848"
namespace = "7c475dad-93cb-4740-941f-1a6636addd93"
group = "SEATA_GROUP"
}
}
seata 注册中心配置
registry 的type直接选nacos,代表从nacos连接Seata-Server,我都nacos上的public组里面有一个seata-searver,分组名称是SEATA_GROUP,所以 namespace 直接配置”” ,或者删掉不配置也行,serverAddr 指向的是你nacos服务的地址,我这里是zjj101:8848, 我不是集群模式 cluster 直接是””,或者不配置cluster 也行, group配置SEATA_GROUP要和nacos控制面板的seata的分组名称保持一致,不然找不到seata服务.
nacos {
serverAddr = “zjj101:8848”
namespace = “”
cluster = “”
group = “SEATA_GROUP”
}
seata的config配置
config {
type = “nacos”
nacos {
serverAddr = “zjj101:8848”
namespace = “7c475dad-93cb-4740-941f-1a6636addd93”
group = “SEATA_GROUP”
}
type=nacos代表seata从nacos上面读取配置, 问这里seata配置单独是放在了seata组里面的,不然配置放到public里面的话,太多了,有100多条,里面就是一些配置,这些配置是导进来的,如果没有导进来就看 https://www.yuque.com/docs/share/d13e525b-1e1b-4a42-8907-e0c9e7e00acb?# 《将seata默认配置导入到nacos配置列表中》 这个帖子,
nacos {
serverAddr = “zjj101:8848”
namespace = “7c475dad-93cb-4740-941f-1a6636addd93”
group = “SEATA_GROUP”
}
serverAddr = “zjj101:8848” 不用说了,就是配置nacos配置中心的地址
namespace 这个配置的参数就是配置中心的seata组的uuid串儿,
group = "SEATA_GROUP" 这个配置就是要和配置中心的Group配置保持一致<br />
事务组配置
在 org.springframework.cloud:spring-cloud-starter-alibaba-seata
的org.springframework.cloud.alibaba.seata.GlobalTransactionAutoConfiguration
类中,默认会使用 ${spring.application.name}-seata-service-group
作为服务名注册到 Seata Server上,如果和service.vgroup_mapping配置不一致,会提示 no available server to connect
错误
也可以通过配置 spring.cloud.alibaba.seata.tx-service-group
修改后缀,但是必须和file.conf
中或者nacos配置中心的配置保持一致
自定义事务组名称需要与seata-server中的对应,具体事务组的作用,回来我稍后研究研究再补上,其实事务组概念我也不是太明白,我觉得就是类似于nacos的Group概念,就是资源隔离的概念,每个事务组可以配置不同的参数,这样更细化,我是这么理解的,如果理解有问题,你们指出来.
调用入口要有@GlobalTransactional注解
调用的地址是: http://localhost:8020/order/test01
com.tuling.order.service.impl.OrderServiceImpl#test01 方法是最上层的入口service方法,需要在这个方法上添加@GlobalTransactional注解,不然会出现分布式事务失效.
启动项目
直接启动OrderServiceApplication和StorageServiceApplication 这两个启动类,
启动完毕,发现nacos多了这两个服务
开始测试
正确的请求
Postman执行 post请求 : http://localhost:8020/order/test01 ,参数是{“count”:1}
执行成功,查看数据库.
发现两个库的表插入成功了,uuid都是ca835d04-8362-48f1-9b44-1e62acd5e0821643795815143
失败的请求
OrderService服务会先执行插入数据到order_tbl表操作,然后再调用StorageService服务准备插入数据到storage_tbl表操作, 在插入之前会触发下面的箭头指向的错误代码,.会抛出来ByZero异常出来
模拟业务失败,当count不是1的时候,这里会抛出ByZero异常出来,
此时数据库里面没有数据,之前测试的数据我已经清掉了
postman执行 post请求: http://localhost:8020/order/test01 参数是:{“count”:2}
执行完了发现报错
查看两个库的两张表,发现并没有新的数据,说明分布式事务发挥作用了