哪些分布式事务的中间件可以保证幂等性?

clipboard.png
如图所示,bool withdraw(account_id, amount)函数表示:从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。
如果withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了withdraw被调用两次,账户也被多扣了一次钱。因此我们要做幂等控制。
问题:
如果采用采用分布式事务,通过引入支持分布式事务的中间件来保证withdraw功能的事务性,有哪些中间件可以提供这些功能?具体怎么实现的啊?

阅读 10.5k
4 个回答

首先,RocketMQ 阿里开源的消息中间件,原来叫做MetaQ,文档里写的是支持分布式事务的,因为RocketMQ的各个环节,包括生产者,消费者,broker都是分布式的,所以基本可以保障由于网络原因丢掉,不过我们在项目中并没有使用这个特性.而且RocketMQ存在重复消费的问题,所以文档明确表明了应该业务方自己实现幂等性.

其次,分布式事务我觉得大多数情况下,应该很少会有真的实现这个东西的.大多数情况下只要保证最终一致性就可以了,分布式事务性能较低.
另外,幂等性和你说的分布式事务其实没多大关系,同样的场景,就算你的系统都在一起,如果接收到两个相同的请求应该如何做?如果没做到幂等性,不是分布式场景下同样会扣多.
而幂等性可以通过颁token等(介绍的文章其实很多)实现

首先,这个场景和分布式的事务其实是没有关系的!
其次,关于服务的幂等性问题,有多种保障方式,具体到你这个场景,可以在协议中定义一个请求表示requestID,在服务端,针对此requestID做验证,比如采用简单的redis分布式锁或者其他分布式锁做幂等性验证即可

涉及到失败重试,所以提供方的接口必须是幂等的,但是诸如扣减库存这种接口很难做到幂等,所以建议把失败接口失败重试关闭。
对于题主的这个场景,主要的原因是调用方因为超时失败了,没有对amount进行回滚,因为我猜的没错的话这应该是一个RPC调用吧,所以题主确实需要分布式事务来执行事务回滚,具体可以参考ByteTCC用TCC的方式也是一种解决方案

可以参考开源分布式事务框架ByteTCC,ByteTCC能从框架层面保障幂等性。

ByteTCC特性:
1、支持Spring容器的声明式事务管理;
2、支持普通事务、TCC事务、业务补偿型事务等事务机制;
3、支持多数据源、跨应用、跨服务器等分布式事务场景;
4、支持长事务;
5、支持dubbo服务框架;
6、支持spring cloud;
7、提供框架层面的幂等性解决方案;

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
1 篇内容引用
推荐问题
宣传栏