-
应用场景
如图所示:假设客户下单过程,将会员服务中当前客户下单数加1, 同时将订单服务新增一条订单数据。
完成这个业务功能2个服务,操作多个数据库。这就涉及到到了分布式事务,需要操作的资源位于多个资源服务器上,而应用需要保证对于多个资源服务器的数据的操作,要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同资源服务器的数据一致性。 -
LCN原理
从代码中得出,用户下单,订单通过feign调用了会员服务。因此: 订单服务是发起方,会员服务是参与方
-
搭建lcn环境
LCN官方文档请查看 https://www.txlcn.org
- 下载LCN
地址: https://github.com/codingapi/tx-lcn/tree/4.1.0 我这里下的是4.1.0版本
解压
目前LCN版本已经升级为4.0以上了,但是官方没有SpringCloud2.0的demo案例。需要对源码进行修改,支持SpringCloud2.0版本,修改源码参考大佬文档: https://www.jianshu.com/p/453741e0f28f
--否则整合的时候会报错,注意我这里是修改过的, - 导入到你的项目中
- 修改tx-manager的application.preperties配置信息
a、修改redis链接地址和密码
b、修改eureka的服务注册地址
tm.compensate.maxWaitTime=5000 根据自己需求更改 - 启动
启动你的eureka-server项目
启动tx-manager项目 启动类:TxManagerApplication.java - 测试
地址 http://127.0.0.1:8899/ - 启动成功后最好手动mvn install到你的maven仓库中去 --入过坑
- 项目中整合lcn
- 在订单服务和会员服务工程中都引入依赖
<!--lcn相关依赖--> <dependency> <groupId>com.codingapi</groupId> <artifactId>transaction-springcloud</artifactId> <version>4.1.2</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.codingapi</groupId> <artifactId>tx-plugins-db</artifactId> <version>4.1.2</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
- 在订单服务和会员服务工程中都配置applicaiton.yml的LCN信息
tm: manager: url: http://127.0.0.1:8899/tx/manager/
- 下载demo,地址https://github.com/codingapi/springcloud-lcn-demo
解压
将文件中TxManagerHttpRequestServiceImpl.java、TxManagerTxUrlServiceImpl.java复制到你的订单和会员服务service或impl包下
- 使用@TxTransaction
修改订单服务的OrderDataService.java@TxTransaction(isStart = true) @Transactional public int addOrderAndMmeber(OrderDataEntity orderDataEntity, Integer memberId){ // 更新下单数量 feignService.updateMember(memberId); // 新增下单记录 int i=10/0; return orderDataMapper.addOrder(orderDataEntity); }
修改会员服务MemberService.java@TxTransaction(isStart = false) @Transactional public int updateMember(Integer id){ return memberMapper.updateMember(id); }
isStart=true 表示是发起方
isStart=false 表示是参与方
--因为这里是订单服务调用的会员服务,所以订单服务是发起方,会员服务是参与方
- 测试
添加报错代码测试@TxTransaction(isStart = true) @Transactional public int addOrderAndMmeber(OrderDataEntity orderDataEntity, Integer memberId){ // 订单服务调用会员服务修改数量 feignService.updateMember(memberId); // 订单服务下单 int i=10/0; return orderDataMapper.addOrder(orderDataEntity); }