什么是事务
事务有四大特性:原子性、一致性、隔离性、持久性。
- 原子性:事务的指令要么都发生,要么都不发生
- 隔离性:不同的事务之间通过一定的策略来防止相互之间的干扰(有读未提交、读已提交、可重复读、串行化读四种)
- 一致性:指程序的执行要确保逻辑一致,例如 A 给 B 转 100,那么 A 一定要扣 100(不能只扣 50),B 一定要加 100(不能只加 50)
- 持久性:事务执行后的数据一定要持久到硬盘中
什么是分布式事务
分布式业务中,我们需要通过 RPC 去调用下游服务,使得整个服务即能解耦,又能完成业务场景。那么如何去保证自身调用多个下游服务后,每个下游服务都能成功或都回退掉,这就需要分布式事务来保证了。
常见的分布式事务有:2PC、3PC、TCC、本地消息表、MQ 事务消息、Sagas 事务模型等。
2PC(两阶段提交)
两阶段提交使用 XA 协议,必须要依赖于数据库的事务,其原理如下:
- 第一阶段:事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并向协调器反馈是否可以提交
- 第二阶段:每个服务有返回可以提交,则协调器发送指令让所有服务提交,否则让所有服务回滚。
优点:尽量保证数据的强一致性,代码编写也比较简单
缺点:依赖于数据库提供的事务方案,如果出现一些不基于数据库的功能,如短信发送等,则不能用此模型,同时其为了保证数据的一致性,牺牲了可用性。
3PC(三阶段提交)
三阶段提交和两阶段提交类似,只不过其添加了一层来判断各服务是否可用。
- 第一阶段:给各服务发送信号,查看各服务是否可用
- 第二阶段:跟 2PC 的第一阶段一样
- 第三阶段:跟 2PC 的第二阶段一样
优点:与 2PC 相比,先去判断各服务是否可用,从而避免了一些服务不可用,但其他服务还傻乎乎的去执行预提交指令,从而提高服务性能。
缺点:跟 2PC 一样。
TCC(补偿事务)
TCC 核心思想:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作,他分为三个阶段:
- Try 阶段:对业务系统做检测以及资源预留
- Confirm 阶段:对业务系统做确认提交,默认 Confirm 阶段是不会出错的(即 Try 成功,Confirm 成功),但也不能绝对保证不会出错
- Cancel 阶段:在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放
举个例子,加入 Bob 要向 Smith 转账,思路大概是:
- 事务协调器调用远程接口,把 Smith 和 Bob 的账户冻结起来
- 在 Confirm 阶段,执行远程调用的转账操作,转账成功进行解冻
参考: