Ensuring Idempotency in Order Services: Preventing Duplicate Orders and Solving the ABA Problem
The article explains how to achieve idempotent order creation and update in distributed systems by using database transactions, unique order identifiers, Redis locks, and version columns to prevent duplicate submissions and resolve the ABA anomaly, ensuring data consistency and reliable user experience.
Problem background : In distributed order systems, network timeouts and automatic retries can cause duplicate requests, leading to multiple inserts and potential over‑charging. Simple front‑end prevention is insufficient; the service layer must guarantee idempotency.
How to avoid duplicate orders :
Each request must carry a unique identifier (e.g., orderId ) that can be used only once.
Record the processing status of each request in the database (e.g., a status field or a payment ledger).
Before handling a request, check whether it has already been processed; if so, reject or ignore it.
Implementation examples:
Use a DB transaction that inserts into both the order table and the order‑item table atomically.
Generate a globally unique orderId via a dedicated service and rely on the DB primary‑key uniqueness to reject duplicate inserts.
Store a flag in Redis, e.g., set order_id payed , and check this flag before processing a repeat request.
ABA problem : When a field (e.g., tracking number) is updated from value A to B and then back to A due to a retry, the system may incorrectly accept the stale A update, corrupting data.
Solution – version column :
Add a version column to the order table.
When reading an order, return its current version to the client.
On update, the client sends back the version; the service executes an atomic SQL such as:
UPDATE orders
SET tracking_number = 666,
version = version + 1
WHERE version = 8;If the version has changed, the update fails, forcing the client to re‑fetch the latest data.
This mechanism prevents both duplicate order creation and ABA anomalies, ensuring that only one successful payment record exists and that concurrent updates are safely serialized.
Summary :
Pre‑generate a unique order number and rely on DB unique constraints for idempotent order creation.
Use a version‑checking update pattern to achieve idempotent updates and solve the ABA problem.
The same principles can be applied to any service that persists data in a relational database.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.