如图所示,bool withdraw(account_id, amount)函数表示:从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。
如果withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了withdraw被调用两次,账户也被多扣了一次钱。因此我们要做幂等控制。
问题:
如果采用采用分布式事务,通过引入支持分布式事务的中间件来保证withdraw功能的事务性,有哪些中间件可以提供这些功能?具体怎么实现的啊?
まず第一に、Alibaba のオープンソース メッセージ ミドルウェアである RocketMQ は、もともと MetaQ と呼ばれていました。ドキュメントには、プロデューサー、コンシューマー、ブローカーを含む RocketMQ のすべての側面が分散されているため、分散トランザクションをサポートしていると記載されています。ネットワーク上の理由で失われることは保証されていますが、プロジェクトではこの機能を使用しませんでした。また、RocketMQ には繰り返し消費の問題があるため、ドキュメントでは冪等性をビジネス側が独自に実装する必要があることが明確に示されています。 >
第二に、ほとんどの場合、分散トランザクションが実装されることはほとんどないと思います。ほとんどの場合、最終整合性を確保するだけで十分であり、分散トランザクションのパフォーマンスは低くなります。さらに、冪等性には実際にはほとんど影響がありません。同じシナリオで、システムがすべて統合されている場合でも、冪等性が達成されない場合は、どうすればよいでしょうか? 分散シナリオでは、さらに多くのリクエストが発生します。
そして冪等性はトークンを発行することで実現できます (実際に多くの記事が紹介されています)
まず第一に、このシナリオは分散トランザクションとは何の関係もありません。
次に、サービスの冪等性については、シナリオに応じてさまざまな方法で保証できます。サーバー側で、この requestID を検証するために、単純なメソッドを使用するなどの方法があります。 redis 分散ロックまたはその他の分散ロックの冪等性を検証できます
失敗時の再試行が含まれるため、プロバイダのインターフェースは冪等である必要があります。ただし、在庫控除などのインターフェースは冪等性を実現することが難しいため、失敗したインターフェースでは失敗した再試行を閉じることをお勧めします。
。質問者のこのシナリオの主な理由は、呼び出し元がタイムアウトで失敗し、ロールバックしなかったことです
amount
。私の推測が正しければ、これは RPC 呼び出しであるはずなので、質問者は本当に分散トランザクションを必要としています詳細については、TCC を使用することも解決策です