分布式事务是无法通过单个数据库事务去控制的,每个微服务都有自己的数据库,一次下单事务需要订单、购物车、商品服务分别执行自己的本地事务,其中一个执行失败其它本地事务是无法回滚的,比如:扣减库存失败无法回滚清理购物车及创建订单的事务。
下边我们测试下单扣减库存,首先部署交易微服务,交易微服务是第一天布置的作业,这里有几点需要注意:
1.需要在ItemClient接口中增加扣减库存的方法,以供交易服务远程调用,还需要在ItemClientFallbackFactory增加扣减库存的降级逻辑,即现在已有的代码【已实现】
@PutMapping("/stock/deduct") public void deductStock(@RequestBody List<OrderDetailDTO> items);
2.商品服务中的OrderDetailDTO移到了hm-api工程,凡是引用该类的微服务都需要统一引用hm-api下的OrderDetailDTO【已实现】
3.交易服务启动类 trade-service 注意添加扫描hm-api下的feign接口
@MapperScan("com.hmall.trade.mapper") @EnableFeignClients(basePackages = {"com.hmall.api"}) @SpringBootApplication(scanBasePackages = {"com.hmall.trade","com.hmall.api"})
4.暂时将“UserContext.getUser()”获取用户id代码固定为“1”。
我们在下单方法代码的最后位置制造异常,如下【注意要有下面的:@Transactional】:
@Override @Transactional public Long createOrder(OrderFormDTO orderFormDTO) { .... if(1==1){ throw new RuntimeException("测试异常"); } return order.getId(); }
预期结果是:当扣减库存成功,下单失败,最终扣减库存事务进行回滚。
此时商品库存我们截个图
下边启动:item-service、trade-service,打开交易服务的swagger文档找到下单接口进行测试:
从商品数据库找一个商品id填入请求参数
最终抛出异常,查看商品的库存正常扣除,但是订单数据没有创建成功,最终导致数据不一致。
测试结论:
通过本地事务控制注解 @Transactional是无法控制分布式事务的。