| The answer is "the same thing as every other concurrency conflict between two requests". In modern backend development this is most commonly handled by the database, and the practical result is that (from the client's perspective) the requests will block, and only one will "actually succeed". Here's a typical example, assuming serializable isolation in a database that uses optimistic concurrency. * Two simultaneous requests come in to create a payment. * The requests provide an idempotency key that is expected to be unique (possibly scoped to a tenant). * The first request starts a transaction and starts processing, everything looks good - no dups. * The second request starts a transaction and starts processing, everything looks good - no dups. * The first one commits and returns success. * The second tries to commit, but a conflict is detected (the first txn committed first). Typically this causes the second transaction to retry. * On retry, the second transaction detects the duplicate. The only question here is what happens when the second transaction fails? The Stripe model is "look up the original response and hand that back to the client". An equally valid and much easier to implement solution is "return a response that tells the client that there was a conflict". Both solutions offer "create payment" as an idempotent operation. |
So when the second request comes in, even though it has the same idempotency key as the first request, the server doesn't check to see if there's already a request received with that idempotency key?
That would seem to defeat the whole purpose of idempotency keys.
> On retry, the second transaction detects the duplicate.
So at this point, the second request would return a 409 code (or something like that) to the client?