-
分布式事务与Seate框架(2)——Seata实践
前言
在上一篇博文(分布式事务与Seate框架(1)——分布式事务理论)中了解了足够的分布式事务的理论知识后,到了实践部分,在工作中虽然用到了Seata,但是自己却并没有完全实践过,所以自己私下花点时间实践以加深理解,实际上在实践过程中遇到了很多的坑(比如Seata与SpringCloudAlibaba的整合中版本兼容性问题,是个很让人头疼的一块,甚至专门去github提过issue),有时候甚至得跟踪源码进行分析,这也使我加强了对阅读源码的能力。总之都是要code的。本篇博文主要结合实践深入讲解Seata AT模式!
参考资料《Spring Cloud Alibaba 微服务原理与实战》(PDF电子书资源,有需要的小伙伴可以评论私信我)、官方wiki
博文中源码已上传至github(https://github.com/Jian0110/learning-cloudalibaba),欢迎小伙伴们star...
一、实践准备工作
1、框架介绍
实践主要是以“订单-库存-账户”系统演示,主要的框架图如下,图中各个部分充当的分布式事务角色已标明。
具体流程:
1)用户登录XXX商品购物系统(假设已有账户),
2)点击购买某个商品,发起创建订单请求;
3)检查购买商品的库存量,如果不够则创建订单失败提示库存不足;否则锁定该商品---->减少库存--->创建订单;
4)订单创建成功后点击付款(或直接付款无需点击,实际上整个Demo中下单之后模拟立马支付,并不会点击付款);
5)如果购买成功则对账户进行余额进行判断,余额足够则进行减扣,余额不够则进行提示说明
6)返回购买成功失败提示说明。
2、项目结构
项目结构如下:
mvn package打包运行seata服务,即运行TC服务器(这里只展示单机)
初始化Seata库,导入sql脚本
二、代码实践
这里只展示关键代码,全部代码已提交gituhb:,有需要的小伙伴可以自行获取
1、“订单-库存-账户”服务
订单服务:
TM(microService):seata-order-service
RM(DB Resources):jdbc:mysql://127.0.0.1:3306/order
OrderService:
OrderController:
调用的Feign:
库存服务:
microService:seata-storage-service
RM(DB Resources):jdbc:mysql://127.0.0.1:3306/storage
StorageService
StorageController:
账户服务:
microService:seata-account-service
RM(DB Resources):jdbc:mysql:127.0.0.1/account
AccountService:
AccountController:
2、Seata服务器,即TC角色
首先初始化seata的sql脚本(sql脚本参考官方wiki),并开启seata库,之后开启Seata Server(具体的配置与启动前nacos配置,事务分组等相关概念请参考官方wiki)
3、检查Nacos服务与配置列表
微服务模块启动后快速注册到dev命名空间下的SEATA_GROUP分组,此时TM、RM、TC都已经具备
启动微服务模块后可以看到日志输出,说明启动成功并且已经成功注册
三、运行测试
1、模拟购买支付成功情况
运行启动所有的微服务后,在TC Serve的日志可以看到所有的TM、RM都已经注册了
此时productId=1库存还剩998
accountId=1的用户余额还剩1000元
接下来就是模拟用户购买商品环节,调用http://localhost:6008/order/create,表示用户想买商品ID=1,价格为12.25的商品
清空日志,并发起请求查看日志:
从日志中我们可以看到:
1)全局事务XID已经生成,各个分支注册成功,
2)branchId也已经生成并在全局事务XID下,资源已被锁住
3)全局事务提交成功
查看此时的库存与余额,都已经进行了减扣
2、模拟库存不足情况
修改productId=1的商品库存为0:
再次发起请求,查看TC Server日志,可以查出明显发生了全局事务的回滚
查看库存与余额情况,库存仍然是0,余额仍然是987.75
3、模拟余额不足情况
修改accountId=1的账户余额小于12.25
再次发起请求,查看日志
不同于库存不足的情况的是,这里库存服务分支事务是先注册TC Server的,因为有异常的并不是库存服务,需要注意的是因为我模拟的是下单之后立马支付,支付失败的话订单也是不会存在,实际生活中应该是订单显示“支付失败”。
查看库存与余额情况,库存仍然是997,余额仍然是10.75
__EOF__