tx

package
v0.0.0-...-7ddf690 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultTimeout = 10 * time.Second

Variables

This section is empty.

Functions

func Do

func Do(ctx context.Context, tx Tx, fn func(ctx context.Context) error) error

func TagPGXTimeoutErr

func TagPGXTimeoutErr(err error) error

func TagSQLiteTimeoutErr

func TagSQLiteTimeoutErr(err error) error

Types

type ErrTagTransactionTimeout

type ErrTagTransactionTimeout struct{ errtag.Internal }

type PGXRepositoryTxer

type PGXRepositoryTxer[R any] struct {
	Config PGXRepositoryTxerConfig[R]
	// contains filtered or unexported fields
}

PGXRepositoryTxer adds transactional behavior to any repository type R. It is typically stored on the repository (often as a pointer) and used to:

  1. Start a transaction and return a repository *copy* bound to that tx.
  2. Run a function inside a transaction with automatic commit/rollback.
  3. Reuse an existing transaction for nested calls (no save points).

Concurrency & Lifetime

  • The root (non-transactional) repository that holds a *PGXRepositoryTxer may be shared across goroutines as long as its underlying DB handle is a pool.
  • A repository instance with an active tx produced by WithTx or BeginTxFunc must not be used concurrently by multiple goroutines. It is bound to a single pgx.Tx (single connection), which is unsafe for concurrent use.
  • Treat tx-bound repository instances as short-lived values scoped to a single unit of work. Avoid storing them in long-lived shared structs.

func NewPGXRepositoryTxer

func NewPGXRepositoryTxer[R any](txer PGXTxer, cfg PGXRepositoryTxerConfig[R]) *PGXRepositoryTxer[R]

NewPGXRepositoryTxer constructs a PGXRepositoryTxer for a concrete repository type R. The withTx function is repository-specific and is responsible for cloning and binding the repo to the provided pgx.Tx (see withTx doc above).

func (*PGXRepositoryTxer[R]) BeginTxFunc

func (r *PGXRepositoryTxer[R]) BeginTxFunc(ctx context.Context, repo R, fn func(ctx context.Context, tx Tx, repo R) error) error

BeginTxFunc starts a new transaction (unless an ambient one is already in progress), clones and binds a repository to that transaction, and invokes fn. On success, the transaction is committed; on error, it is rolled back. If an ambient transaction exists (txn != nil), it is reused and fn is called directly.

Nested behavior:

  • Nested calls reuse the ambient transaction. Save points are not created.

Panic semantics:

  • If fn panics, the helper attempts to roll back the transaction and then re-panics. If rollback itself fails, the panic is annotated accordingly.

func (*PGXRepositoryTxer[R]) InTx

func (r *PGXRepositoryTxer[R]) InTx() bool

InTx reports whether this txer is currently inside a transaction.

func (*PGXRepositoryTxer[R]) WithTx

func (r *PGXRepositoryTxer[R]) WithTx(repo R, tx Tx) R

WithTx returns a tx-bound copy of repo using the provided transaction. If this PGXRepositoryTxer already represents an in-flight transaction (txn != nil), the original repo is returned unchanged (ambient tx reuse).

Panics if tx does not implement pgx.Tx.

type PGXRepositoryTxerConfig

type PGXRepositoryTxerConfig[R any] struct {
	// Timeout is the maximum duration allowed for the entire transaction. Must
	// be a positive duration up to 10 seconds otherwise DefaultTimeout
	// is used.
	Timeout time.Duration

	// WithTxFunc returns a tx-bound copy of the repo using the provided
	// transaction. If the PGXRepositoryTxer already represents an in-flight
	// transaction, the original repo is returned unchanged (ambient tx reuse).
	//
	// The function must:
	//   - Clone the repo value passed in.
	//   - Bind the clone to the provided transaction (e.g. sqlc.Queries.WithTx).
	//   - Set the provided *PGXRepositoryTxer on the clone so nested calls reuse
	//     the ambient transaction.
	//   - Return the clone.
	//
	// NOTE: WithTxFunc receives a copied PGXRepositoryTxer whose transaction is
	// set for the lifetime of the new repository instance.
	WithTxFunc func(repo R, txer *PGXRepositoryTxer[R], tx pgx.Tx) R
}

type PGXTxer

type PGXTxer interface {
	BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error)
}

PGXTxer is implemented by types that can begin a pgx-backed transaction. In pgx/v5 both pgxpool.Pool and pgx.Conn expose BeginTx methods that satisfy this interface.

type Repository

type Repository[R any] interface {
	// WithTx returns a copy of the repository bound to the provided transaction.
	// The returned repository executes all database operations using the given
	// transaction context.
	//
	// This is typically called by BeginTxFunc to build a new repository instance
	// scoped to the lifetime of the transaction. Nested transactional calls
	// reuse the existing transaction, returning the original repository unchanged.
	WithTx(tx Tx) R

	// BeginTxFunc begins a new transaction (unless one is already in progress)
	// and executes fn with a tx-bound repository. The transaction is
	// automatically committed if fn returns nil, or rolled back if fn returns
	// an error or panics.
	//
	// Nested Behavior:
	//
	//   - If a transaction is already active (i.e. called within another
	//     BeginTxFunc or WithTx context), the existing transaction is reused
	//     and fn is invoked directly without starting a new transaction.
	//
	// Panic Semantics:
	//
	//   - If fn panics, the transaction helper will attempt to roll back and
	//     re-panic. If rollback itself fails, the panic message is annotated
	//     accordingly.
	//
	// Timeouts:
	//
	//   - Transactions should be configured with a timeout to avoid deadlocks.
	//     When timeout occurs, the returned error must be tagged with
	//     ErrTagTransactionTimeout.
	BeginTxFunc(ctx context.Context, fn func(ctx context.Context, tx Tx, repo R) error) error
}

Repository is a generic interface implemented by repository types that support transactional operations. It defines the minimum set of methods required to integrate with tx helpers such as PGXRepositoryTxer and SQLRepositoryTxer.

The type parameter R represents the concrete repository type, allowing WithTx and BeginTxFunc to return or receive type-safe repository instances.

Typical usage:

repo.BeginTxFunc(ctx, func(ctx context.Context, tx tx.Tx, repo MyRepository) error {
    // Perform one or more operations using the tx-bound repository.
    if err := repo.CreateEntity(ctx, entity); err != nil {
        return err
    }
    return nil
})

Concurrency & Lifetime

  • The root (non-transactional) repository may be shared safely across goroutines if its underlying database handle supports concurrency (e.g. *pgxpool.Pool or *sql.DB).
  • A repository instance returned by WithTx or created within BeginTxFunc is bound to a single transaction (and thus a single connection) and must not be shared across goroutines.

type SQLTxWrapper

type SQLTxWrapper struct {
	// contains filtered or unexported fields
}

SQLTxWrapper adapts *sql.Tx to the Tx interface used by Do. It allows database/sql transactions to integrate with generic commit/rollback helpers without leaking driver-specific APIs.

func NewSQLTxWrapper

func NewSQLTxWrapper(tx *sql.Tx) *SQLTxWrapper

NewSQLTxWrapper wraps an *sql.Tx to satisfy the Tx interface.

func (*SQLTxWrapper) Commit

func (s *SQLTxWrapper) Commit(ctx context.Context) error

Commit commits the underlying SQL transaction.

func (*SQLTxWrapper) GetSQLTx

func (s *SQLTxWrapper) GetSQLTx() *sql.Tx

GetSQLTx returns the underlying *sql.Tx. This is primarily used internally by repository binders (the withTx function) to rebind sqlc.Queries or other database handles.

func (*SQLTxWrapper) Rollback

func (s *SQLTxWrapper) Rollback(_ context.Context) error

Rollback rolls back the underlying SQL transaction.

type SQLiteRepositoryTxer

type SQLiteRepositoryTxer[R any] struct {
	Config SQLiteRepositoryTxerConfig[R]
	// contains filtered or unexported fields
}

SQLiteRepositoryTxer adds transactional behavior to any SQLite-compatible repository type R (works with modernc.org/sqlite, libsql, and other drivers).

It is typically stored on the repository (often as a pointer) and used to:

  1. Start a transaction and return a repository *copy* bound to that tx.
  2. Run a function inside a transaction with automatic commit/rollback.
  3. Reuse an existing transaction for nested calls (no save points).

Concurrency & Lifetime

  • The root (non-transactional) repository that holds a *SQLiteRepositoryTxer may be shared across goroutines.
  • A repository instance with an active tx produced by WithTx or BeginTxFunc must not be used concurrently by multiple goroutines. It is bound to a single sql.Tx (single connection), which is unsafe for concurrent use.
  • Treat tx-bound repository instances as short-lived values scoped to a single unit of work. Avoid storing them in long-lived shared structs.

func NewSQLiteRepositoryTxer

func NewSQLiteRepositoryTxer[R any](db SQLiteTxer, cfg SQLiteRepositoryTxerConfig[R]) *SQLiteRepositoryTxer[R]

NewSQLiteRepositoryTxer creates a SQLite txer with sane defaults.

func (*SQLiteRepositoryTxer[R]) BeginTxFunc

func (r *SQLiteRepositoryTxer[R]) BeginTxFunc(
	ctx context.Context,
	repo R,
	fn func(ctx context.Context, tx Tx, repo R) error,
) error

BeginTxFunc starts a new transaction (unless an ambient one is already in progress), clones and binds a repository to that transaction, and invokes fn. On success, the transaction is committed; on error, it is rolled back. If an ambient transaction exists (txn != nil), it is reused and fn is called directly.

Nested behavior:

  • Nested calls reuse the ambient transaction. Save points are not created.

Panic semantics:

  • If fn panics, the helper attempts to roll back the transaction and then re-panics. If rollback itself fails, the panic is annotated accordingly.

func (*SQLiteRepositoryTxer[R]) InTx

func (r *SQLiteRepositoryTxer[R]) InTx() bool

InTx reports whether this txer is currently inside a transaction.

func (*SQLiteRepositoryTxer[R]) WithTx

func (r *SQLiteRepositoryTxer[R]) WithTx(repo R, txn Tx) R

WithTx returns a tx-bound copy of repo using the provided transaction. If this SQLiteRepositoryTxer already represents an in-flight transaction (txn != nil), the original repo is returned unchanged (ambient tx reuse).

Panics if tx is not an *SQLTxWrapper.

type SQLiteRepositoryTxerConfig

type SQLiteRepositoryTxerConfig[R any] struct {
	// Timeout is the maximum duration allowed for the entire transaction. Must
	// be a positive duration up to 10 seconds otherwise DefaultTimeout
	// is used.
	//
	// Timeout is applied by:
	//   - Running the transaction under a context deadline.
	//   - Setting PRAGMA busy_timeout to the same duration (unless NoPragma
	//     is true).
	Timeout time.Duration

	// NoPragma disables PRAGMA statements (e.g. busy_timeout) inside
	// transactions. Set this to true when using a SQLite driver or backend
	// that does not support PRAGMAs.
	NoPragma bool

	// WithTxFunc returns a tx-bound copy of the repo using the provided
	// transaction. If the SQLiteRepositoryTxer already represents an in-flight
	// transaction, the original repo is returned unchanged (ambient tx reuse).
	//
	// The function must:
	//   - Clone the repo value passed in.
	//   - Bind the clone to the provided transaction (e.g. sqlc.Queries.WithTx).
	//   - Set the provided *SQLiteRepositoryTxer on the clone so nested calls
	//     reuse the ambient transaction.
	//   - Return the clone.
	//
	// NOTE: WithTxFunc receives a copied SQLiteRepositoryTxer whose transaction
	// is set for the lifetime of the new repository instance.
	WithTxFunc func(repo R, txer *SQLiteRepositoryTxer[R], tx *sql.Tx) R
}

type SQLiteTxer

type SQLiteTxer interface {
	BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
	Conn(ctx context.Context) (*sql.Conn, error)
}

SQLiteTxer starts SQLite transactions (typically *sql.DB).

type Tx

type Tx interface {
	Commit(ctx context.Context) error
	Rollback(ctx context.Context) error
}

Jump to

Keyboard shortcuts

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