Mastering Idempotency: Ensure Reliable Operations in Distributed Systems

Idempotency ensures that repeated service calls or user actions produce the same effect without unintended side effects, a critical concern in distributed and microservice architectures; this article explains its principles, SQL examples, HTTP semantics, token strategies, lock handling, and message‑queue solutions.

Architect
Architect
Architect
Mastering Idempotency: Ensure Reliable Operations in Distributed Systems

Idempotency Introduction

In modern distributed or micro‑service architectures, service calls may be retried or invoked multiple times, leading to latency or failure. To guarantee consistent results—especially in scenarios such as payments—business logic must be idempotent.

Definition

Idempotency means that multiple executions of an operation have the same effect on resources as a single execution; the result may differ, but the state does not change after the first successful call.

SQL Examples

Consider the following statements: select * from table where id=1 This SELECT query can be executed any number of times without changing data, thus it is idempotent. insert into table(id,name) values (1,'heima') If id or name has a unique constraint, the statement can insert only one row, making it idempotent; otherwise it is not. update table set score=100 where id=1 Repeated execution always produces the same data change, so it is idempotent.

Design Dimensions

Idempotency is considered from two dimensions:

Space : defines the scope, e.g., an order must not be created twice.

Time : defines the validity period; some operations require permanent idempotency (order, payment), others only for a limited window.

Locks are often introduced to handle concurrent safety.

Business Scenarios

Multiple clicks on a “place order” button should generate only one order.

Payment should be deducted only once regardless of retries.

Inventory deduction must occur once per successful payment.

Shipping should be triggered only once per order.

Implementing idempotency adds complexity and may reduce throughput, so it should be applied based on concrete business needs.

HTTP Protocol Idempotency

RESTful APIs define idempotent semantics for common HTTP methods:

GET : safe and idempotent; multiple calls do not affect resources.

POST : not idempotent; each call may create a new resource.

PUT : idempotent; repeated calls produce the same effect.

DELETE : idempotent; repeated deletions have the same outcome.

Interface Idempotency – Token Mechanism

A common solution is to issue a one‑time token to the client. The server stores the token (e.g., in Redis for distributed systems) and validates it on each request.

@Component
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        // Pass token
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            if (request != null) {
                Enumeration<String> headerNames = request.getHeaderNames();
                while (headerNames.hasMoreElements()) {
                    String headerName = headerNames.nextElement();
                    if ("token".equals(headerName)) {
                        String headerValue = request.getHeader(headerName);
                        requestTemplate.header(headerName, headerValue);
                    }
                }
            }
        }
    }
}

The server checks the token existence in Redis; if present, it processes the request and then deletes the token. If absent, the request is considered duplicate.

Token mechanism diagram
Token mechanism diagram

In high‑concurrency scenarios, a race condition may allow two requests to pass before the token is deleted. One remedy is to serialize the operation with a thread lock, at the cost of throughput.

Anti‑Duplicate Table

Another approach is to create a dedicated table with a unique index on fields that identify a request. Insertion into this table succeeds only once; subsequent attempts fail, preventing duplicate processing.

Message Idempotency

When using message queues, retries can cause the same message to be delivered multiple times. Ensuring idempotency at the consumer side is essential.

RabbitMQ Retry and Compensation

RabbitMQ retries messages when the consumer throws an exception. After a configurable number of retries, the message can be moved to a dead‑letter queue for manual compensation.

Message retry diagram
Message retry diagram
# Consumer listener configuration
listener:
  simple:
    retry:
      enabled: true
      max-attempts: 5
      initial-interval: 3000

Message Idempotency Solutions

Use a Redis‑backed deduplication key.

Employ a deduplication table similar to the service‑side approach.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Message QueueIdempotencyToken
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

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.