Backend Development 9 min read

Ensuring Idempotency in Order Creation: Database Constraints, Unique Order IDs, and Versioning to Prevent Duplicate Orders and ABA Problems

The article explains how to achieve idempotent order creation and updates by using database transactions, unique order identifiers, Redis flags, and version columns to prevent duplicate inserts, handle retry scenarios, and solve the ABA problem in distributed backend systems.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Ensuring Idempotency in Order Creation: Database Constraints, Unique Order IDs, and Versioning to Prevent Duplicate Orders and ABA Problems

Problem Background

The simplest case involves a DB transaction when creating an order: inserting records into the order table and order‑item table must occur within the same transaction.

If the Order service calls the Pay service and a network timeout occurs, the Order service may retry, causing the Pay service to receive the same payment request twice on different nodes, so the interface must guarantee idempotency.

How to Avoid Duplicate Orders

Front‑end can prevent duplicate form submissions, but network errors and automatic retries in RPC frameworks mean duplicate requests can still reach the back‑end, so the service itself must ensure idempotency.

How to Determine a Duplicate Request

Check the order table before inserting, but defining “duplicate order” in SQL is difficult.

Identical user, product, and price may still be a legitimate consecutive order.

To guarantee idempotency, the following measures are needed:

Each Request Must Have a Unique Identifier

For example, a payment request must include an orderId that can only be successfully paid once.

Record a Flag After Processing a Request

Store a status field in MySQL, such as a payment record for the order before processing payment.

Check If the Request Has Been Processed Before

If an order is already paid, a payment record exists; a duplicate request will cause a unique‑key violation on INSERT , preventing double charging.

MySQL’s primary key enforces uniqueness: providing a primary key that already exists causes the INSERT to fail, which can be used to achieve idempotent order creation.

Provide an “orderId generation” API that returns a globally unique order number; the front‑end obtains this ID before submitting the order, and the same ID is used in the create‑order request.

The order ID becomes the primary key of the order table, so duplicate requests carry the same ID, and the DB’s unique constraint ensures only one successful insert.

In practice, combine this with Redis: use the orderId as a unique key, set a flag like set order_id payed after a successful payment record, and reject further payments for the same ID.

Solving the ABA Problem

What Is ABA

When a seller enters a tracking number (e.g., 666), corrects it to 888, and a retry causes the old 666 request to be processed again, the tracking number may revert incorrectly.

Solution Using Version Columns

Add a version column to the order table. Each query returns the current version, which the front‑end sends back when updating.

The order service compares the provided version with the stored one:

If they differ, reject the update.

If they match, update the data and increment version by 1 within the same transaction.

Example SQL:

UPDATE orders set tracking_number = 666, version = version + 1 WHERE version = 8;

This ensures that between reading and updating, no other modification has occurred; otherwise the update fails and the client must reload the latest version.

Using the version column, the two ABA cases are handled: the stale 666 update fails because the version has changed, and a retry of the same request also fails, preventing incorrect data.

Summary

Create order service can pre‑generate a unique order ID and rely on the DB’s unique constraint to achieve idempotent order creation.

Update order service can use a version‑number mechanism to detect concurrent modifications, increment the version atomically, and thus solve the ABA problem while ensuring idempotent updates.

These idempotent techniques can be applied to any service that persists data in a database with a primary‑key table.

transactionDatabaseRedisIdempotencyVersioningorder creation
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.