如图所示,bool withdraw(account_id, amount)函数表示:从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。
如果withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了withdraw被调用两次,账户也被多扣了一次钱。因此我们要做幂等控制。
问题:
如果采用采用分布式事务,通过引入支持分布式事务的中间件来保证withdraw功能的事务性,有哪些中间件可以提供这些功能?具体怎么实现的啊?
먼저 Alibaba의 오픈소스 메시지 미들웨어인 RocketMQ는 원래 MetaQ라고 불렸습니다. 문서에는 생산자, 소비자, 브로커 등 RocketMQ의 모든 측면이 분산되어 있으므로 분산 트랜잭션을 지원한다고 명시되어 있습니다. 네트워크 문제로 인해 손실될 수 있다는 점은 보장되지만 프로젝트에서는 이 기능을 사용하지 않았습니다. 게다가 RocketMQ는 반복적인 소비 문제가 있으므로 비즈니스 측에서 자체적으로 멱등성을 구현해야 한다는 점을 문서에 명확하게 나와 있습니다. >
둘째, 분산 트랜잭션은 거의 구현되지 않는 경우가 대부분이라고 생각합니다. 대부분의 경우 최종 일관성은 충분하고 분산 트랜잭션의 성능은 낮습니다.게다가 멱등성은 실제로 멱등성과 거의 관련이 없습니다. 언급한 분산 트랜잭션. 동일한 시나리오에서 시스템이 모두 함께 있더라도 두 개의 동일한 요청을 받으면 어떻게 해야 합니까? 멱등성이 달성되지 않으면 분산 시나리오에서도 더 많은 공제가 발생합니다. 🎜> 그리고 토큰을 발행하여 멱등성을 달성할 수 있습니다(실제로 소개된 기사가 많이 있습니다)
우선 이 시나리오는 분산거래와는 전혀 관련이 없습니다!
둘째, 서비스의 멱등성을 보장하는 방법은 다양합니다. 프로토콜에서 requestID를 나타내는 요청을 정의할 수 있습니다. 서버 측에서는 간단한 방법을 사용하여 이 requestID를 확인할 수 있습니다. redis 분산 잠금 또는 기타 분산 잠금의 멱등성을 확인할 수 있습니다
실패 시 재시도가 포함되므로 공급자의 인터페이스는 멱등성을 가져야 합니다. 그러나 인벤토리 공제와 같은 인터페이스는 멱등성을 달성하기 어렵기 때문에 실패한 인터페이스에서는 실패한 재시도를 닫는 것이 좋습니다.
질문자의 이 시나리오에서 주된 이유는 호출자가 시간 초과로 인해 실패하고 롤백하지 않았기 때문입니다.
amount
제 추측이 맞다면 이는 RPC 호출이어야 하므로 질문자에게는 분산 트랜잭션이 꼭 필요하기 때문입니다. 자세한 내용은 ByteTCC를 사용하는 것도 해결책입니다