Documentation
¶
Overview ¶
Package postgres wraps github.com/jackc/pgx/v5 (pgxpool) with resilient defaults so a service gets a correctly configured PostgreSQL connection pool from a single New call: sensible pool sizes, a connect timeout, a health-check period, and a startup Ping that verifies readiness. Functional options tune the pool, timeouts, and an optional pgx QueryTracer. RunInTx runs a function inside a transaction and retries automatically on serialization failures (SQLSTATE 40001) and deadlocks (40P01) with capped exponential backoff. The returned DB exposes the underlying *pgxpool.Pool for the full pgx API.
Index ¶
- func Retryable(err error) bool
- type DB
- type Option
- func WithConnectTimeout(d time.Duration) Option
- func WithHealthCheckPeriod(d time.Duration) Option
- func WithMaxConnIdleTime(d time.Duration) Option
- func WithMaxConnLifetime(d time.Duration) Option
- func WithMaxConns(n int32) Option
- func WithMinConns(n int32) Option
- func WithTracer(t pgx.QueryTracer) Option
- func WithTxRetry(attempts int, base, max time.Duration) Option
- type TxOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB is a thin, resilient wrapper over a pgx connection pool. Build one with New; use Pool to reach the full pgx API, RunInTx to run a transaction with automatic serialization-failure retries, Healthy for a liveness probe, and Close to release the pool. A DB is safe for concurrent use by multiple goroutines.
func New ¶
New parses the DSN, builds a pgx connection pool with the resilient defaults for anything left unset, and verifies readiness with a Ping before returning. The DSN accepts either a keyword/value string or a URL, for example "postgres://user:pass@localhost:5432/acme". On a failed Ping the pool is closed and the error is returned, so a returned DB is always usable. The ctx bounds both the pool creation and the readiness Ping.
Example ¶
Connect to a server with the resilient defaults, then query through the underlying pgx pool.
package main
import (
"context"
"log"
"time"
postgres "github.com/Bugs5382/go-postgres"
)
func main() {
ctx := context.Background()
db, err := postgres.New(ctx, "postgres://user:pass@localhost:5432/acme")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var now time.Time
if err := db.Pool().QueryRow(ctx, "SELECT now()").Scan(&now); err != nil {
log.Fatal(err)
}
}
Output:
Example (Options) ¶
Tune the pool and the transaction retry policy through functional options.
package main
import (
"context"
"log"
"time"
postgres "github.com/Bugs5382/go-postgres"
)
func main() {
ctx := context.Background()
db, err := postgres.New(ctx,
"postgres://user:pass@localhost:5432/acme",
postgres.WithMaxConns(50),
postgres.WithConnectTimeout(5*time.Second),
postgres.WithHealthCheckPeriod(time.Minute),
postgres.WithTxRetry(10, 5*time.Millisecond, time.Second),
)
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
Output:
func (*DB) Close ¶
func (db *DB) Close()
Close releases the connection pool and waits for in-flight queries to finish. It is safe to call once; further use of the DB after Close returns errors from pgx.
func (*DB) Healthy ¶
Healthy reports whether the server answers a Ping within ctx. It is cheap and suitable for readiness and liveness probes.
func (*DB) Ping ¶
Ping verifies a round-trip to the server within ctx, acquiring and releasing a pooled connection. It returns the underlying error on failure.
func (*DB) Pool ¶
Pool returns the underlying pgx pool so callers can use the full pgx API (Query, Exec, CopyFrom, LISTEN/NOTIFY, and so on). The returned value is owned by this DB; do not Close it directly -- use DB.Close.
func (*DB) RunInTx ¶
RunInTx runs fn inside a transaction and commits it. If fn or the commit fails with a serialization failure (SQLSTATE 40001) or a deadlock (40P01), the whole transaction is retried from the top with capped exponential backoff, up to the configured attempt limit. Any other error -- including an application error returned by fn -- aborts immediately without a retry. fn must be idempotent across attempts: it may run more than once, and it must not commit or roll back the transaction itself. The default policy comes from WithTxRetry; per-call TxOptions override it and set the pgx transaction options (for example Serializable isolation, where retries are expected under contention).
Example ¶
RunInTx retries automatically on serialization failures, which are expected under Serializable isolation. fn must be safe to run more than once.
package main
import (
"context"
"log"
postgres "github.com/Bugs5382/go-postgres"
"github.com/jackc/pgx/v5"
)
func main() {
ctx := context.Background()
db, err := postgres.New(ctx, "postgres://user:pass@localhost:5432/acme")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.RunInTx(ctx, func(tx pgx.Tx) error {
var balance int
if err := tx.QueryRow(ctx, "SELECT balance FROM accounts WHERE id = $1", 1).Scan(&balance); err != nil {
return err
}
_, err := tx.Exec(ctx, "UPDATE accounts SET balance = $1 WHERE id = $2", balance-100, 1)
return err
}, postgres.WithIsolation(pgx.Serializable))
if err != nil {
log.Fatal(err)
}
}
Output:
type Option ¶
type Option func(*config)
Option configures a DB. Options are applied in order by New; a later Option wins over an earlier one.
func WithConnectTimeout ¶
WithConnectTimeout bounds how long a single connection attempt may take. A non-positive duration keeps the default.
func WithHealthCheckPeriod ¶
WithHealthCheckPeriod sets how often the pool checks the health of idle connections. A non-positive duration keeps the default.
func WithMaxConnIdleTime ¶
WithMaxConnIdleTime caps how long a connection may sit idle before it is closed. A non-positive duration keeps the default.
func WithMaxConnLifetime ¶
WithMaxConnLifetime caps how long a connection may live before it is retired and replaced. A non-positive duration keeps the default.
func WithMaxConns ¶
WithMaxConns sets the maximum number of connections in the pool. A non-positive size is ignored, keeping the resilient default.
func WithMinConns ¶
WithMinConns sets the minimum number of idle connections the pool keeps warm. A negative value is ignored; zero is a valid setting (no warm minimum).
func WithTracer ¶
func WithTracer(t pgx.QueryTracer) Option
WithTracer installs a pgx QueryTracer on every connection, enabling query tracing without pulling a telemetry library into the core. For OpenTelemetry, use the otel subpackage, which supplies a tracer through this seam. A nil tracer is ignored.
func WithTxRetry ¶
WithTxRetry sets the default transaction retry policy RunInTx applies: attempts is the maximum number of tries (not extra retries), and base/max bound the exponential backoff between them. attempts below 1 and non-positive backoff bounds are ignored, keeping the defaults. A per-call TxOption (WithAttempts, WithBackoff) overrides this.
type TxOption ¶
type TxOption func(*txConfig)
TxOption configures a single RunInTx call. Options are applied in order; a later Option wins over an earlier one.
func WithAttempts ¶
WithAttempts overrides the maximum number of tries for this call. A value below 1 is ignored, keeping the DB default.
func WithBackoff ¶
WithBackoff overrides the exponential backoff bounds for this call. Non-positive bounds are ignored, keeping the DB default.
func WithIsolation ¶
func WithIsolation(level pgx.TxIsoLevel) TxOption
WithIsolation sets only the transaction isolation level for this call, leaving the other pgx transaction options unchanged.
func WithTxOptions ¶
WithTxOptions sets the pgx transaction options (isolation level, access mode, deferrable) for this call. Use it to run under Serializable isolation, where serialization failures -- which RunInTx retries -- are expected under contention.