世界性技术难题:分布式事务之TCC

阿里称已有一种解决世界性难题的方案,无论是效率还是可靠性都超过目前的分布式事务技术

可惜是收费的,还必须依赖阿里云的分布式数据库

分布式事务就是一个大操作分成很多小操作,在不同服务器上,最后要么一起成功,或一起失败,必须是一个整体性的事务

比如淘宝买吃的,要减库存然后扣钱,库存和扣钱是两个服务,如果扣钱失败了,那么库存要还原,反之一样
不把分布式事务处理好,后果很严重

TCC分布式事务

TCC的意思很简单,T(Try)C(Confirm)C(Cancel)

TCC之Try

以上面打的比方为例,买吃的下单逻辑大概是这样:

订单一般都有状态,那么应该改一下代码

1
2
// 修改订单状态为更新中
orderService.updateStatus("OrderStatus.UPDATEING");

意思就是别着急把状态改为“已支付”,先给个预备状态“修改中”

然后减库存也是,可以先冻结库存(先修改库存为98也可以),比如100-2=98,然后把2存到一张冻结表里,表示有2个库存被冻结

同理,扣钱也是,比如支付100,放冻结表里,表示有100块要扣除

以上就是TCC的Try阶段:不是直接完成业务操作逻辑,而是完成一个Try操作
这个操作会锁住一些资源

TCC之Confirm

上面操作完成之后,会有2个结果,成功或失败

如何知道结果?需要引入TCC框架:

框架名称Github地址star数量
tcc-transactionhttps://github.com/changmingxie/tcc-transaction2446
Hmilyhttps://github.com/yu199195/hmily1381
ByteTCChttps://github.com/liuyangming/ByteTCC1300
EasyTransactionhttps://github.com/liuyangming/ByteTCC904

如果Try阶段全部成功,内嵌的TCC框架能感知到,会进入下一个Confirm阶段

那么就需要手动改之前的状态了

1
2
// 修改订单状态为:已支付
orderService.updateStatus("OrderStatus.PAYED");

其他库存/扣钱服务都需要修改,将冻结的库存和钱修改为0,完成一个正常的扣减
框架会自动执行各个服务的逻辑

TCC之Cancel

如果扣钱服务异常,TCC框架也会感知到,会对整个TCC事务进行回滚,即执行Cancel阶段

跟上面一样,也需要修改状态

1
2
// 修改订单状态为:已取消
orderService.updateStatus("OrderStatus.CANCELED");

既然扣钱失败,库存那边肯定已经减了,就需要将库存还原
把冻结的库存和钱减去,加到原库存和钱里去

ps:上面例子的状态,不是必须有的,看业务是否需要

TCC总结

1.要用TCC事务需引入TCC事务框架
2.原本1个接口,要改为3个逻辑(Try-Confirm-Cancel)
3.Cancel和Confirm逻辑必须要幂等

如果在CC阶段,服务突然挂掉了,会反复调用,直到成功(一致性) tips:可以设置最大重试次数,实在不行人工操作
如果中间件/数据库挂了,会执行Cancel,Try回滚

优点

1.降低锁冲突
2.将数据库的2PC提到应用层来实现,数据库是1PC,提高吞吐量

缺点

1.代码量增多,开发成本高
2.业务侵入


摘自:
石杉的架构笔记

------本文结束感谢阅读------
0%