分布式事务

Posted by Keal on March 7, 2021

解决分布式事务的其中一种方法就是不使用分布式事务.

概念

分布式系统中数据并非保存在同一个数据库中,此时的事务如果跨多个数据库,则无法使用数据库本身的事务来完成,需要额外的机制来实现分布式事务.

基于分布式的CAP理论,由于一般无法接受网络分区,因此P必须保证,所以剩下的就是C跟A. 根据这种情况又进一步提出了BASE理论(BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写。是对CAP中AP的一个扩展)

实现分布式事务的方案

2PC(二阶段提交)

引入了一个事务管理器:第一阶段对所有服务进行一个提议(propose),第二阶段根据各个节点的vote结果进行commit或者rollback操作

优点:正常情况下保证了强一致性

缺点:

  1. 事务管理器也需要做备份,否则一旦事务管理器宕机,各个服务无法会阻塞在等待commit或rollback的请求上
  2. 第二阶段会阻塞资源数据
  3. 如果因为网络问题在事务管理器向节点发起commit请求后,资源管理器部分收到,则没法保证数据一致
  4. 事务管理器提议后宕机,在备份的事务管理器恢复前,又一个数据节点宕机,那么剩余的节点是执行commit还是rollback需要等待节点也恢复才能继续进行. (因为宕机恢复后的事务管理器需要获取到所有节点的vote信息)

3PC(三阶段提交)

在2PC的中间引入了precommit阶段,来解决2pc的第四个缺点, 因为只有所有vote都是赞同才进入precommit阶段,因此可以据此来判断宕机的节点是否投过赞成票,如果是则恢复后commit,如果否则终止事务.

TCC

把动作分成了Try, Confirm, Cancel三个阶段

  • Try阶段:尝试执行,完成所有业务检查(一致性),预留必须业务资源(准隔离性)
  • Confirm阶段:确认执行真正执行业务,不作任何业务检查,只使用Try阶段预留的业务资源,Confirm操作满足幂等性。要求具备幂等设计,Confirm失败后需要进行重试。
  • Cancel阶段:取消执行,释放Try阶段预留的业务资源 Cancel操作满足幂等性Cancel阶段的异常和Confirm阶段异常处理方案基本上一致。

基于MQ的事务

通过MQ可以实现最终一致性. 通过将事务内容存储到额外的MQ中,通过失败重发等方式保证消息最终一定能够被消费到,来保证最终一致性.

如果有业务需要有回退的场景, 则可以在多次尝试失败后, 不再重发而进行回退(非必要的情况下不建议,因为场景复杂度增加)