Go

database/sql — Transaction Helper

admin by @admin ADMIN
5d ago
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
Wrap your transaction in a function that commits on success and rolls back on error or panic. Drop-in: pass any `func(*sql.Tx) error` and forget about manual cleanup.
Go
Raw
package main

import (
    "context"
    "database/sql"
)

func WithTx(ctx context.Context, db *sql.DB, fn func(*sql.Tx) error) (err error) {
    tx, err := db.BeginTx(ctx, nil)
    if err != nil { return err }

    defer func() {
        if p := recover(); p != nil {
            _ = tx.Rollback()
            panic(p)                              // re-panic after rollback
        } else if err != nil {
            _ = tx.Rollback()
        } else {
            err = tx.Commit()
        }
    }()

    return fn(tx)
}

// Usage
//
// err := WithTx(ctx, db, func(tx *sql.Tx) error {
//     if _, err := tx.ExecContext(ctx, "INSERT INTO orders ..."); err != nil {
//         return err     // auto-rollback
//     }
//     _, err := tx.ExecContext(ctx, "UPDATE inventory SET qty = qty - 1 WHERE id = ?", 42)
//     return err
// })
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.