Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/sqltransaction"
Package sqltransaction executes business logic inside a transaction with begin/commit/rollback control flow and consistent error handling.
How It Works
Exec and ExecWithOptions execute a caller-provided ExecFunc inside a
transaction:
- Start transaction via
DB.BeginTx. - Run the provided function with
*sql.Tx. - Commit on success.
- Roll back automatically if the function fails or commit is not reached.
Rollback behavior is guarded to avoid noisy false failures:
- rollback is skipped after successful commit,
sql.ErrTxDoneduring rollback is ignored,- rollback failures are joined with the current error for full diagnostics.
Usage
err := sqltransaction.Exec(ctx, db, func(ctx context.Context, tx *sql.Tx) error {
// Execute all related SQL operations using tx.
// Return an error to trigger rollback.
return nil
})
if err != nil {
return err
}
For a similar helper using github.com/jmoiron/sqlx instead of database/sql, see: github.com/tecnickcom/nurago/pkg/sqlxtransaction
When To Use
- Several statements must succeed or fail together.
- You want rollback guaranteed on error and on panic, without repeating the boilerplate.
Example
// A real program would use a *sql.DB from sql.Open. The mock keeps the
// example self-contained and its output deterministic.
db, mock, err := sqlmock.New()
if err != nil {
fmt.Println(err)
return
}
defer func() { _ = db.Close() }()
mock.ExpectBegin()
mock.ExpectExec("UPDATE balance").WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectCommit()
// The transaction is committed when run returns nil, and rolled back
// when it returns an error or panics.
err = sqltransaction.Exec(
context.TODO(),
db,
func(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, "UPDATE balance SET amount = amount - 10 WHERE id = 1")
if err != nil {
return fmt.Errorf("debiting account: %w", err)
}
return nil
},
)
fmt.Println("committed:", err)
// Output:
// committed: <nil>
Full source is in example_sqltransaction_test.go. More runnable examples are on pkg.go.dev.
Dependencies
This package reaches no external module: it uses only the Go standard library.