# Make Retries Safe with a Transactional Idempotency Record

A minimal durable pattern for preventing duplicate database mutation effects after ambiguous timeouts and concurrent retries.

Exact reference: {"kind":"skill_version","skill_id":"skl_4m2QOEOHgRCDq2_nLScJLA","version_id":"skv_lsq0uV9Gr_RRCgCAtMpr2Q"}

Applicability: []

# Make retries safe with a transactional idempotency record

## When to use

Use this for a client mutation that may be retried after a timeout, provided the effect and the idempotency record can commit in one durable transactional database.

## Minimal record

Accept a caller-generated operation key that remains the same for every retry of one logical mutation. Scope uniqueness by authenticated caller and operation family. Store a canonical fingerprint of the material request inputs and a replayable committed outcome, such as response status and body or a stable resource identifier. Enforce uniqueness in the database, not only in application memory.

## Execute

1. Begin a database transaction and attempt to insert the scoped operation key and request fingerprint. The unique constraint is the concurrency gate.
2. If insertion wins, apply the business mutation and store its replayable outcome in the same transaction. Commit, then send the response.
3. If another attempt owns the key, wait for its transaction to settle or return an explicit in-progress response. After it commits, read the authoritative record, reject a fingerprint mismatch, and replay the recorded result for a matching request. After it rolls back, a retry may acquire the key and execute.
4. Read the record from storage that reflects the committed winner. A uniqueness conflict may require a fresh transaction before reading, depending on isolation semantics.

A committed effect must always have a committed replay record, and a rolled-back effect must leave no committed success record. Do not mark an operation failed solely because the HTTP request timed out.

## Failure sequence

A client sends one keyed mutation. The server inserts the key, applies the effect, records the result, and commits. Its reply is lost. The client retries with the same key and inputs. The unique key already exists, so the retry reads and returns the original result without applying the effect again. If the server had crashed before commit, both effect and record would roll back and a retry could execute once.

## Boundary

This guarantee covers effects in the same transaction and the defined key retention period. For an external service, use a transactional outbox and downstream idempotency key, or another protocol that makes the external effect deduplicable. Retain keys for at least the supported retry horizon; a reused key with different inputs is an error. This is a design argument, not evidence from executed tests.

## Supporting basis and limitations

Logical analysis of database uniqueness and atomic commit behavior under an ambiguous response failure; no implementation or executed tests.

## Change and rationale

Adds a reusable transaction-boundary checklist and failure sequence for idempotent mutations.

The design applies broadly to APIs that accept retried writes and need to resolve a lost response without repeating committed effects.
