How to Use Database Transactions Correctly in Go

Start a transaction with BeginTx, execute queries, and use defer with Rollback to ensure data consistency before committing.

Use db.BeginTx with a context to start a transaction, execute your queries, and then either Commit or Rollback based on the result.

ctx := context.Background()
tx, err := db.BeginTx(ctx, nil)
if err != nil {
    // handle error
}
defer tx.Rollback() // Rollback if Commit fails or panics

_, err = tx.ExecContext(ctx, "INSERT INTO users (name) VALUES (?)", "Alice")
if err != nil {
    return err // Rollback happens automatically via defer
}

return tx.Commit()

This pattern ensures that if any query fails, the defer statement rolls back the transaction, preventing partial data writes. If all queries succeed, Commit finalizes the changes and the defer becomes a no-op.