PGX Pool PostgreSQL Query Timeouts
Drive PostgreSQL through a pgx connection pool with statement timeouts, health pings, and context-scoped transactions.
Code
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
func newPool(ctx context.Context, databaseURL string) (*pgxpool.Pool, error) {
config, err := pgxpool.ParseConfig(databaseURL)
if err != nil {
return nil, fmt.Errorf("parse dsn: %w", err)
}
config.MaxConns = 20
config.MinConns = 4
config.MaxConnLifetime = 30 * time.Minute
config.MaxConnIdleTime = 5 * time.Minute
config.HealthCheckPeriod = 30 * time.Second
pool, err := pgxpool.NewWithConfig(ctx, config)
if err != nil {
return nil, fmt.Errorf("create pool: %w", err)
}
pingCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
if err := pool.Ping(pingCtx); err != nil {
pool.Close()
return nil, fmt.Errorf("verify connectivity: %w", err)
}
return pool, nil
}
func withTx(ctx context.Context, pool *pgxpool.Pool, fn func(ctx context.Context) error) error {
tx, err := pool.Begin(ctx)
if err != nil {
return fmt.Errorf("begin: %w", err)
}
defer tx.Rollback(ctx) // 提交后回滚是空操作,安全兜底
if err := fn(ctx); err != nil {
return err
}
return tx.Commit(ctx)
}
func main() {
pool, err := newPool(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
fmt.Println(err)
return
}
defer pool.Close()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var version string
if err := pool.QueryRow(ctx, "select version()").Scan(&version); err != nil {
fmt.Println("query failed:", err)
return
}
fmt.Printf("connected to: %.32s\n", version)
}Report a problem with this exampleOpens a pre-filled issue on GitHub.