订单业务的一致性(CAP中的C【Consistency】)-01问题的提出

it2025-03-26  10

为什么需要分布式事务?本地事务不够用吗?

1.下面以一个具体的例子展开讨论。

张三在商城上下单买了2台法拉利,每台400万。 业务交代清楚了。

2.这样的代码应该怎么写呢?

//点击提交订单按钮的时候,问题来了 @Transactional @Override public SubmitOrderRespVo submitOrder(OrderSubmitVo orderSubmitVo) { if (checkValidity() ) {//校验合法性,如果一切合法,则开始提交代码 // 1.1把订单保存在订单表中 saveOrder(order); // 1.2调用库存服务吧库存减去2 R r = wareFeignService.orderLocKStock(orderSubmitVo); // 1.3调用用积分服务给张三添加800万积分 R r = pointsFeignService.upPoint(orderSubmitVo); return submitOrderRespVo; } } } }

上面的示意代码比较简单,使用openfign调用远程服务区扣减库存和提升积分。

特别注意@Transactional说明这是一个本地事务。

3.在一下地方出现问题会出现什么问题?

@Transactional是一个本地事务,能控制住saveOrder(order),但是使用feign调用远程的服务这个@Transactional就鞭长莫及了。所以如果

R r = wareFeignService.orderLocKStock(orderSubmitVo); R r = pointsFeignService.upPoint(orderSubmitVo);

出问题应该会不好办,我们做具体分析。

3.1把订单保存在订单表中出现问题了

如果saveOrder(order) 出现问题了,上面已经提到则@Transactional可以完满控制。

3.2调用库存服务把库存减去2出现问题了

问题一:为什么出现问题,可能是网络原因,下面就是一种情形:由于网络抖动,outOfTime了。这个时候,@Transactional获得消息,出现了异常就会做回滚操作,具体做什么事呢?就是把saveOrder(order);的执行重新吐出来。但是不好意思,刚才仅仅是网络抖动,其实已经成功了。我去,数据不一致了。我想要的应该是要成功都成功,要失败都失败呀。这个就是需要分布式事务的原因之一。 问题二:库存服务事务自制,如果出现问题,会自己回滚,但是订单感知不到。原因之二。

3.3调用积分服务给张三添加800万积分成功了,但是后面服务处理问题

此时,库存服务、订单服务均成功了。由于事务自制,不会进行回滚,但是订单服务在本事务@Transactional内会回归。原因之三。

4总结

处于以上三个原因,可能还有更多其他原因,导致,继续要呼吁一种分布式事务的解决方案,来处理这个问题。 下一篇:订单业务的一致性(CAP中的C【Consistency】)-02CAP介绍

前路无畏 认证博客专家 专家认证 自律的艰辛总甜过懊悔的苦果!专注于java后端技术及解决方案,善于总结,分享!自律的艰辛总甜过懊悔的苦果!专注于java后端技术及解决方案,善于总结,分享!自律的艰辛总甜过懊悔的苦果!专注于java后端技术及解决方案,善于总结,分享!
最新回复(0)