Photo Finish Charge

Your charge endpoint looks up the idempotency key, and if no row exists it creates the charge and then inserts the key with the result. A flaky client sends the same key twice about 30 ms apart and both requests hit different application instances. Two charges are created. What actually failed, and what fixes it?

A

The client reused a key it should not have, so enforcing a shorter expiry on stored keys stops a stale key from colliding with a fresh request

B

Read-check-act is not atomic across instances, so both requests saw no key; insert the key first under a unique constraint and let the loser return the stored or in-progress result

C

The lookup and the charge were not in one transaction, so wrapping the whole handler in BEGIN and COMMIT makes the second request block until the first commits and then read its key row

D

The two instances have clock skew, so stamping each request with a timestamp column and keeping only the earlier of the two collapses them into a single charge