03 / 05

How do you manage database transactions correctly in Go, including error handling?

Begin a transaction, defer a rollback immediately, execute queries with error checking, and commit at the end. The deferred rollback is a no-op if Commit has already been called.

Correct transaction pattern
Transaction best practices
  1. 1

    Defer Rollback immediately after BeginTx — ensures rollback on any error path

  2. 2

    Pass tx as a DBTX interface to repository functions for unit-of-work reuse

  3. 3

    Keep transactions short — long-running transactions hold locks and cause contention

  4. 4

    Handle serialization failures (pgcode 40001) with retry logic for high-contention scenarios

  5. 5

    Use savepoints for nested transaction-like behavior within a single transaction