Help us shape the future of Go! Take the 2026 Go Developer Survey

pgtx

package module
v1.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 5 Imported by: 0

README

pgtx

CI

Transaction management for Go + PostgreSQL, built on pgx/v5 and avito-tech/go-transaction-manager v2. A transaction whose context ends is rolled back and its connection returned to the pool (v1 left it acquired forever).

A Trm manager owns transaction boundaries; a context-aware DB executor transparently routes queries to the active transaction (or the pool when there is none), so repositories stay unaware of whether they run inside a transaction. Generic Do* helpers wrap a unit of work in a chosen isolation level and return its result.

pgtx/                 NewTxManager / NewTxDB constructors (single pgtx.go)
pkg/tx/               Trm, DB, executor, settings, Do* helpers, tx concurrency guard
contrib/otel/         pgxpool → OpenTelemetry metrics (its own go.mod)

Install

go get github.com/gopherex/pgtx

Usage

pool, _ := pgxpool.New(ctx, dsn)

mgr, err := pgtx.NewTxManager(pool, tx.Serializable())
if err != nil {
    return err
}

// context-aware executor: uses the in-context transaction when present
db := pgtx.NewTxDB(trmpgx.DefaultCtxGetter)

// run a unit of work in a transaction, get a typed result back
user, err := tx.DoSerializableRet(ctx, mgr, func(ctx context.Context) (User, error) {
    return repo.FindAndUpdate(ctx, db, id)
})

Isolation-level helpers: tx.Serializable, tx.RepeatableRead, tx.ReadCommitted, tx.ReadUncommitted, plus the Do* / Do*Ret runners.

Transaction concurrency guard

pgx.Tx does not allow two statements on one transaction at the same time: a goroutine spawned with the transaction context (errgroup and friends) would otherwise hit a busy-conn or protocol error that does not name the cause. Every transaction begun by NewTxManager is therefore guarded: while a call still holds the transaction — its Rows are not drained or closed, its Row is not scanned, its BatchResults are not closed — every other call routed into it, at any savepoint level, is refused with tx.ErrTxInUse before reaching pgx. A refusal never damages the transaction: it stays usable. Sequential code, nested savepoints and the pool path outside transactions are untouched — pool access stays fully concurrent, the guard costs ~15 ns per statement.

OpenTelemetry metrics

The contrib/otel module exposes pgxpool statistics as OpenTelemetry metrics. It is a separate module so the core stays free of the OTel dependency:

go get github.com/gopherex/pgtx/contrib/otel
import pgtxotel "github.com/gopherex/pgtx/contrib/otel"

if err := pgtxotel.RegisterMetrics(pool); err != nil {
    return err
}

License

MIT — see LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewTxDB

func NewTxDB(defaultTr trmpgx.Tr, options ...tx.DbOption) tx.DB

NewTxDB creates a new TxExecutor with the given defaultTr and options.

Parameters: - defaultTr: The default transaction to use. - options: Optional configurations for the TxExecutor.

Returns: - *TxExecutor: The newly created TxExecutor.

func NewTxManager

func NewTxManager(
	pool *pgxpool.Pool,
	settings *trmpgx.Settings,
) (tx.Trm, error)

NewTxManager creates TX manager with pgxpool.Pool. Put constructor for TX manage here since manager depends on pgx5 driver. Transactions it begins are guarded against concurrent use (tx.ErrTxInUse); the pool path stays fully concurrent.

Types

This section is empty.

Directories

Path Synopsis
contrib
otel module
pkg
tx

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL