分布式事务

在一个项目中的事务,我们可以使用 Spring 的 @Transactional 来控制。
但它只支持一个 JVM,在分布式环境中,涉及到了多个系统,部署在不同的 JVM 中,就不能用 @Transactional 来控制事务了。

方案一(使用消息保证最终一致性)

以经典的转账问题为例,小明有两张银行卡,分别是 银行A 和 银行B 的,现在从 A卡 转 1000 给 B卡,分两步:A卡 余额减少、B卡 余额增加。两家银行的系统肯定不在一台服务器上,这时就用到了分布式事务。
使用消息保证最终一致性
① 银行A 给 RocketMQ 发送消息,状态为待执行。
② 银行A 处理业务。(余额减去 1000)
③ 银行A 给 RocketMQ 发送结果消息,如果 银行A 很久没有发送结果,RocketMQ 会轮询所有待执行的消息,调用 银行A 的接口,查看结果。(成功:RocketMQ 修改消息状态、失败:RocketMQ 删除消息)
④ RocketMQ 给 银行B 提供消息。
⑤ 银行B 处理业务。(余额加上 1000,如果 银行B 处理失败,会不断的去 RocketMQ 取消息并执行,所以要保证业务处理的幂等性)

方案二(尽最大努力去通知)

这个方案适用于成功最好,不成功也没有严重后果的事务。如:下单后的短信通知。
尽最大努力去通知
① 下单系统 处理业务。(下单)
② 如果下单成功,下单系统 给 MQ 发送消息。
③ RocketMQ 给 通知服务 提供消息。
④ 通知服务调用 短信系统 的接口。(如果失败了,通知服务会重试 N 次,N 可配置)

方案三(TCC)

这是一种强一致性方案,有补偿机制,适用于需要严格保证事务一致性的业务,如:银行。

  • T(Try):检测并锁定资源。
  • C(Confirm):执行。
  • C(Cancel):回滚。

还是以转账问题为例,从 A卡 转 1000 给 B卡,分两步:A卡 余额减少、B卡 余额增加。

  • Try:冻结 银行A 和 银行B 的账户。
  • Confirm:银行A 和 银行B 处理业务。(A卡 余额减去 1000,B卡 余额加上 1000)
  • Cancel:如果任何一方失败,就回滚。(需要实现回滚的业务代码)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值