Skip to main content
This tutorial assumes you are running under isolation, which requires client-side retry handling for .
When a is unable to complete due to with another concurrent or recent transaction attempting to write to the same data, CockroachDB will without involving the client (i.e., silently). An automatic retry may not always succeed if the transaction is SERIALIZABLE. In this case, a is emitted to the client. This page presents an example of an application’s transaction retry logic, as well as a manner by which that logic can be tested and verified against your application’s needs.

Client-side retry handling example

The Python-like pseudocode below shows how to implement an application-level retry loop; it does not require your driver or ORM to implement , so it can be used from any programming language or environment. In particular, your retry loop must:
  • Raise an error if the max_retries limit is reached
  • Retry on 40001 error codes
  • at the end of the try block
  • Implement exponential backoff logic as shown below for best performance

Test transaction retry logic

To test your application’s transaction retry logic, use the . When inject_retry_errors_enabled is set to true, any statement (with the exception of ) executed in the session inside of an explicit transaction will return a with the message restart transaction: TransactionRetryWithProtoRefreshError: injected by `inject_retry_errors_enabled` session variable. If the client retries the transaction using the special , after the 3rd retry, the transaction will proceed as normal. Otherwise, the errors will continue until the client issues a SET inject_retry_errors_enabled=false statement. For example, suppose you’ve written a wrapper function with some retry logic named run_transaction that you want to use to execute statements across a psycopg2 connection. In this example, run_transaction takes a SQL-executing function op(conn) and attempts to run the function, retrying on serialization failures (exposed in pscyopg2 as the SerializationFailure exception class) with exponential backoff, until reaching a maximum number of tries:
You can add a quick test to this function using the inject_retry_errors_enabled session variable.
Calling run_transaction without an op input sets inject_retry_errors_enabled as true until the final retry attempt, before which the inject_retry_errors_enabled is set back to false. For all attempts except the last one, CockroachDB will inject a retryable serialization error for the client to handle. If the client cannot handle the error properly, the retry logic isn’t working properly.