分布式事务的产生和解决

问题的产生

服务化之后,整个系统拆分为多个服务,用户的一个操作,可能会设计到多个服务,而每个服务都是一个单独到数据库,可能是在不同的实例上,也有可能在不同的服务器上,这个时候如果要用到事务就比较麻烦,会设计到分布式事务。

DEMO

比如下订单,可能会设计到订单服务、商品服务器、购物车服务等,必须保证所有服务都能够成功调用,在没有分布式之前,我们可以直接用事务,把相关都操作都写到一个事务中,而分布式之后,则会设计到多个服务。这个时候,就必须要考虑分布式事务如何去实现了。

解决方案:

XA协议:XA分布式事务协议

XA协议分为:事务协调者和事务参与者

第一阶段
协调者负责协调事务参与者,当需要执行事务的时候,协调者会西安通知所有的事务参与者做好准备,此时事务不提交,如果所有的参与者都返回ok,第一阶段准备工作完成
第二阶段
协调者通知所有事务参与者提交事务,事务参与者自己提交事务,释放资源,告诉协调者成功,所有参与者都返回成功之后,则分布式事务完成。

可能出现的问题
如果在第一阶段,有事务参与者返回失败,则所有参与者都中止后续都操作。

如果在第二阶段出现问题,事务协调者则通知其他参与者都回滚事务,实现一致性。

缺点:

1.性能问题
XA协议遵循强一致性。在事务执行过程中,各个节点占用着数据库资源,只有当所有节点准备完毕,事务协调者才会通知提交,参与者提交后释放资源。这样的过程有着非常明显的性能问题。
2.协调者单点故障问题
事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,参与者收不到提交或是回滚通知,参与者会一直处于中间状态无法完成事务。
3.丢失消息导致的不一致问题。
在XA协议的第二个阶段,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。

TCC

补偿事务(TCC)
TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:

  1. 阶段主要是对业务系统做检测及资源预留
  2. Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功
  3. Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
举个例子,假入 Bob 要向 Smith 转账,思路大概是:

我们有一个本地方法,里面依次调用
1、首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
2、在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
3、如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

使用消息队列解决

使用消息队列,可以把相关需要做的操作,分开为几步操作,把对应的消息内容写入队列中,异步去处理。写入队列成功,则说明成功,消费者异步去处理队列中的数据即可。

拿提交订单来说:【强一致性变为最终一致性】

  1. 创建订单,把相关的数据数据写入对应的订单队列中
  2. 调用仓储服务,减去对应商品的库存,把需要减的库存也写入对应的队列中
  3. 在调用购物车相关的接口,去删除对应的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奇葩也是花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值