Annotation Interface Idempotent


@Retention(RUNTIME) @Target(METHOD) public @interface Idempotent
Marks an action as idempotent, meaning it can be safely retried without causing duplicate side effects.

Idempotent actions are important for reliability:

  • Safe to retry on timeout or network errors
  • Can be called multiple times with same result
  • Enable aggressive retry policies
  • Support at-least-once delivery semantics

Examples of Idempotent Operations

  • GET requests (read-only)
  • PUT/PATCH with same data (update to fixed state)
  • DELETE by ID (already deleted = success)
  • Set value operations (vs increment)

Examples of NON-Idempotent Operations

  • POST to create new resources
  • Increment/decrement operations
  • Append to list operations
  • Payment processing (without idempotency key)

Usage


 @ActionSpec(type = ActionType.WEB_SERVICE, endpoint = "...")
 @Idempotent
 public User getUser(String userId) {
     // Safe to retry - just reads data
     return null;
 }

 @ActionSpec(type = ActionType.WEB_SERVICE, endpoint = "...")
 @Idempotent(key = "orderId", description = "Uses order ID as idempotency key")
 public Order updateOrderStatus(String orderId, String status) {
     // Safe to retry - sets to fixed state
     return null;
 }

 @ActionSpec(type = ActionType.WEB_SERVICE, endpoint = "...")
 // NOT marked as @Idempotent - creates new resource each time
 public Order createOrder(OrderRequest request) {
     return null;
 }
 

Retry Behavior

When an action is marked as idempotent:

  • Framework may apply more aggressive retry policies
  • Retries on timeout are safe
  • Can use at-least-once delivery without deduplication

Idempotency Keys

For actions that need idempotency keys (like payment processing), use the key attribute to specify which parameter contains the idempotency key. The framework can then:

  • Cache results by idempotency key
  • Return cached result on retry instead of re-executing
  • Detect duplicate submissions
Author:
TnsAI Team
See Also:
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Optional description explaining why this action is idempotent.
    Parameter name that serves as the idempotency key.
    int
    Time-to-live for idempotency key cache in seconds.
    boolean
    Whether to allow retry on any error.
  • Element Details

    • description

      String description
      Optional description explaining why this action is idempotent. Useful for documentation and code review.
      Returns:
      description of idempotency
      Default:
      ""
    • key

      String key
      Parameter name that serves as the idempotency key. When specified, the framework can cache results by this key and return cached results on retry.

      Example: For a payment action, the order ID or transaction ID can serve as the idempotency key.

      Returns:
      parameter name for idempotency key, or empty if not applicable
      Default:
      ""
    • keyTtlSeconds

      int keyTtlSeconds
      Time-to-live for idempotency key cache in seconds. After this duration, the same key can trigger a new execution. Default is 24 hours (86400 seconds).
      Returns:
      TTL in seconds
      Default:
      86400
    • retryOnAnyError

      boolean retryOnAnyError
      Whether to allow retry on any error. If false, only network/timeout errors trigger retry. If true, business logic errors also trigger retry.
      Returns:
      true to allow retry on any error
      Default:
      false