下边为了简化分析过程 我们仍然以下单扣减库存为例说明:
在单体架构下实现下单减库存,如下图:
用户请求订单服务,订单服务请求数据库完成创建订单扣减库存,通过本地事务实现,代码如下:
begin transaction; //1.本地数据库操作:创建订单 //2.本地数据库操作:减去库存 commit transation;
如果是在微服务架构下,如下图:
用户请求订单服务下单,订单服务请求库存服务扣减库存。
此时代码变为下边这样:
begin transaction; //1.本地数据库操作:创建订单 //2.远程调用:减去库存 commit transation;
设想: 当远程调用扣减库存成功了,由于网络问题远程调用并没有返回,此时本地事务提交失败就回滚了创建订单的操作,此时订单没有创建成功而库存却扣减了,最终就导致了下单扣减库存整个事务的数据不一致。
因此在分布式架构下,基于数据库的事务控制无法满足要求,下单操作是一次本地事务,扣减库存是一次本地事务,两次本地事务组成一个完整的事务即下单扣减库存,数据库的本地事务只能控制一次本地事务即下单操作控制下单的本地事务,扣减库存操作控制扣减库存的本地事务,无法保证下单和扣减库存整体事务的原子性和一致性。
造成分布式事务无法控制的根本原因是不同业务的数据通常不在一个数据库中或者不在一个系统中,一次事务需要由多个服务或多个系统远程调用协作完成,远程协作依赖网络,由于网络问题会导致整体事务不能正常完成。
分布式事务的典型场景是:业务的数据分布在多个数据库,一次事务操作需要跨多个数据库去完成,
需要由多个服务远程调用协作去完成,远程调用依赖网络,由于网络问题会导致整体事务不能正常完成。
如下图所示:
还有非典型的分布式事务场景也需要了解下。
1)单服务请求多数据库完成一次事务
下图中虽然没有跨服务远程调用但一次事务请求两个不同的数据库也属于分布式事务的场景,创建订单会和订单数据库创建连接通过一次本地事务提交数据,减库存会和商品数据库创建连接通过一次本地事务提交数据,因为下单扣减库存是通过两个数据库连接完成,仍然是多次本地事务共同完成一个完整的事务。
2)多服务请求单数据库完成一次事务
下图中虽然用的一个数据库但是通过跨服务远程调用去完成一次事务,也属于分布式事务的场景。
思考下这种场景为什么也属于分布式事务?