解决方案
方式1:2PC(两阶段提交协议)
参考:https://www.cnblogs.com/balfish/p/8658691.html
- 1、应用程序连接两个数据源。
- 2、应用程序通过事务协调器向两个库发起prepare ,两个数据库收到消息分别执行本地事务( 记录日志),不提交,如果执行成功则回复yes ,否则回复no。
- 3、事务协调器收到回复,只要有一方向复no则分别向参 与者发起回滚事务,参与者开始回滚事务。
- 4、事务协调器收到回复,全部回复yes ,此时向参与者发起提交事务。如果参与者有一方提交事务失败则由事务协调器发起回滚事务。
2PC
- 优点:实现强一致性,部分关系数据库支持( Oracle、MySQL等)。
- 缺点:整个事务的执行需要由协调者在多个节点之间去协调,增加了事务的执行时间,性能低下。
- 解决方案有: springboot+Atomikos or Bitronix
3PC
方式2:事务补偿(TCC)
TCC事务补偿是基于2PC实现的业务层事务控制方案,它是Try、Confirm和Cancel三个单词的首字母,含义如下:
- 1、Try检查及预留业务资源完成提交事务前的检查,并预留好资源。
- 2、Confirm 确定执行业务操作、对try阶段预留的资源正式执行。
- 3、Cancel 取消执行业务操作、对try阶段预留的资源释放。
1、Try
下单业务由订单服务和库存服务协同完成,在try阶段订单服务和库存服务完成检查和预留资源。订单服务检查当前是否满足提交订单的条件(比如:当前存在未完成订单的不允许提交新订单)。库存服务检查当前是否有充足的库存,并锁定资源。
2、Confirm
订单服务和库存服务成功完成Try后开始正式执行资源操作。订单服务向订单写一条订单信息。库存服务减去库存。(真实向数据库写入数据)
3、Cancel
如果订单服务和库存服务有一方出現失敗則全部取消操作。订单服务需要刪除新増的订单信息。库存服务减去的库存还原(事务补偿)
优点:最终保证数据的一致性,在业务层实现事务控制,灵活性好。
缺点:开发成本高,每个事务操作每个参与者都需要实现try/confirm/cancel三个接口(由程序员自己实现)。
注意: TCC的try/confirm/cancel接口都要实现幂等性,在为在try、confirm. cancel失败后要 不断重试。
什么是幂等性?
幂等性是指同一个操作无论请求多少次,其结果都相同。
幂等操作实现方式有:
- 1、操作之前在业务方法进行判断如果执行过了就不再执行。
- 2、缓存所有请求和处理的结果,已经处理的请求则直接返回结果。
- 3、在数据库表中加一个状态字段(未处理,已处理) , 数据操作时判断未处理时再处理。
方式3:消息队列实现最终一致性
将分布式事务拆分成多个本地事务来完成,并且由消息队列异步协调完成