分布式事务TCC
大家好,今天想和大家一起聊聊分布式事务。
今天主要说主要内容如下:
* 分布式事务TCC
我们知道布式式事物TCC代表Try、Confirm、Cancel,就是尝试、确认、取消。这个是互联网上比较常见的分布式事务。首先它的运行逻辑如下图。
执行步骤是这样的:
- 提供两个服务,服务A和服务B
- 每个服务里边需要行提供try、conform、cancel的方法用于执行。
- 当业务发起分布式事物调用之后,先记录到日志中,然后执行try操作,如果没有问题的话执行confirm操作。
- 如果其中某个过程出现了问题此时需要执行cancel操作。
举个例子:
购买一件商品,那么我们有几个服务,一个是订单服务,一个是库存服务,还是一个是货运的服务,当我们购买了一件商品之后,订单服务的状态会变为支付成功,库存的服务将会减少,货运会将这商品进行出库。
此时,我们的try操作就是将这几个服务做成一个“冻结”状态,confirm就是将“冻结”的状态变为“非冻结”,这个时间就是操作成功了,cancel就是将“冻结”状态进行变为之前的形态。我们直接将这个状态由结果变为正在进行的状态,这种好处是可以进行还原,并且设计的时候还能保留结果。
try时各个服务的处理:
订单服务:将订单状态由UNPAID(未支付)变为PAYING(支付中)
库存服务:设置一个frozen_num, 比如库存10个,购买2个。库存数量变为8,frozen_num 变为2,即冻结了2个。
货运服务:货运服务将2个购买的做一个货运单,状态为PREPARING(备货中)
confirm时各个服务的处理
订单服务:将订单的状态变为PAIED(支付成功)
库存服务:将frozen_num由2变为0,说明已经成功卖出去了
货运服务:货运单的状态变为READY(可以发货)
cancel时各个服务的处理
订单服务:状态变为CANCELED(取消)
库存服务:frozen_num变为0,同时库存服务由8变为10个
货运服务:货运服务将2个商品的货运单状态变为CANCELED(取消)
通过这样的服务设计,我们能够很好的将服务在各个状态中转换。当然,里边还有很多细节,比如,某个服务出现了问题,库存服务出现问题了,我们应该怎么办?
我们可以看到图版中还有一个事物协调器,当事务执行try调用所有服务成功的同时也需要执行的中间过程数据进行记录,比如购买库存数2,它的作用就是当某个服务出现问题时可以进行快速的回滚操作。事物协调器也执行confirm、cancel,假如一个服务confirm失败后,则它会调用另外两个服务的cancel方法。
我们执行try成功后,在执行confirm的时候,库存服务出现了问题,比如服务机器挂了,此时我们应该有一个任务,会不断的调用这个库存服务,当然尝试的次数也是有一定的时间间隔,这个可以由我们自己根据业务进行设计,比如一个指数级重试。如果重试到一定次数的时候,那么就需要进行提醒人工进行处理。cancel也同理,这样设计的目的是防止出现服务问题导致的数据不一致。
因为TCC是柔性事物架构,所以互联网大厂使用的也很多。支持的框架也不少,比如tcc-tranaction, ByteTCC, seata都是支持。
使用TCC的时候,我们需要自己大量写一些try、confirm、cancel的逻辑,这样业务代码量也会相对不少,但是由于可以处理高并发量的请求,也深受很多大厂的喜欢。