Around Go: SQL services · 3 MIN READ

SQL retries: restart a safe transaction, reconcile an unknown result

Separate retryable transaction aborts from an ambiguous committed operation.

Retrying the last failed SQL statement can be wrong when an earlier statement read stale state or the transaction is already aborted. A safe retry policy names the driver error, restarts the complete business unit when appropriate, stays within a total deadline and prevents repeated external effects.

SQL retries: restart a safe transaction, reconcile an unknown result · A MAP OF THE IDEA

  1. Classify the outcome
  2. Choose one retry owner
  3. Respect the total budget
  4. Reconcile durable identity

Useful when

  • Separate retryable transaction aborts from an ambiguous committed operation.
  • Retry a documented safe unit within one budget. Reconcile uncertain commit outcomes through durable operation identity rather than assuming an error proves no effect occurred.

Watch out

  • Retry classification is driver-specific. Preserve one total deadline and use durable deduplication for ambiguous side effects.

Implementation & operation cost: Choose the policy from the actual contract, then verify its failure path in the target environment.

01

Classify with the real driver

For PostgreSQL, serialization_failure is SQLSTATE 40001 and deadlock_detected is 40P01. Inspect structured driver errors rather than parsing an English error message. Those codes are not interchangeable with a lost network response, which can leave an outcome unknown.

go
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
	retryable := pgErr.Code == "40001" || pgErr.Code == "40P01"
	_ = retryable // apply the caller's bounded whole-transaction policy
}
Read the code

The native fragment imports errors and github.com/jackc/pgx/v5/pgconn. It only classifies two PostgreSQL conditions; it is not a complete retry loop and does not claim every network or database error is retryable.

02

Give one layer the retry budget

Use a small reviewed attempt cap, bounded jittered delay and the remaining overall deadline. Recreate the transaction and re-read necessary state on each attempt. Do not let HTTP, application and driver retries multiply independently into a storm while every request retains a connection or body.

03

Reconcile transport ambiguity

If a payment-like command committed but its reply was lost, retrying without an operation identity can duplicate the transition. Store a scoped idempotency key and request fingerprint under a uniqueness rule. Return the prior result or reconcile provider state; a transaction cannot un-send a remote charge.

04

Test the windows, not only the loop count

Inject a known abort before commit, an exhausted deadline, concurrent duplicate commands and commit-then-disconnect. Assert one durable business effect and a useful response classification. Include isolation and schema compatibility in a release rollback plan; reverting a binary does not erase committed data.

TAKE THIS WITH YOU

Retry a documented safe unit within one budget. Reconcile uncertain commit outcomes through durable operation identity rather than assuming an error proves no effect occurred.

Check your understanding

A network error occurs after the server may have committed a charge. What is the safe next step?

Go to the source

Progress stays in this browser. No account needed.