生产环境必须用 pgxpool.pool 而非 pgx.conn,因后者无连接复用;sql.open 不建连接,须立即 db.ping() 验证;事务内所有操作必须用 tx.xxx,严禁混用 db.xxx;扫描 null 必用指针或 sql.nullxxx。

用 database/sql + pgx 或 lib/pq 连 PostgreSQL,别碰 github.com/jackc/pgx/v5 的非连接池接口
Go 官方 database/sql 是标准入口,但底层驱动决定行为。现在主流选 pgx(性能好、原生类型支持全),次选 lib/pq(维护少、已归档)。直接用 pgx.Conn(非 pgxpool.Pool)会漏掉连接复用,高并发下秒变 dial tcp: lookup xxx: no such host 或 too many connections。
- 生产环境一律用
pgxpool.Pool,不是pgx.Connect -
lib/pq的sslmode=disable在本地开发可省事,但上线必须配sslmode=require或更严格模式 - 连接字符串里别硬编码密码,用
user=xxx password=xxx@host:port/dbname格式容易被日志/监控误采,改用postgres://user:pass@host:port/dbname?sslmode=require
sql.Open 不真连数据库,db.Ping() 才校验连接有效性
很多人写完 sql.Open("pgx", connStr) 就以为连上了,结果后续 Query 报 sql: database is closed 或 connection refused——因为 sql.Open 只初始化驱动和连接池参数,不建任何 TCP 连接。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 初始化后立刻跟
err := db.Ping(context.Background()),失败就 panic 或重试,别往后拖 - 如果用
pgxpool.Pool,Ping会从池里取一个连接做握手,比lib/pq更快返回真实状态 - 在 Kubernetes 环境里,
Ping失败常见于服务 DNS 解析未就绪,加个简单重试逻辑比等 readiness probe 更可控
事务里别混用 db.Query 和 tx.Query,否则锁表或死锁
用 db.Begin() 开启事务后,所有 SQL 操作必须走 tx 对象,不能穿插用原始 db。否则看似正常,实则:查询可能读到未提交数据(取决于隔离级别)、UPDATE 可能锁住不该锁的行、甚至触发 PostgreSQL 的 ERROR: current transaction is aborted, commands ignored until end of transaction block。
- 事务内所有
Query/Exec/QueryRow都调tx.XXX,不是db.XXX - 别在事务里调
db.Close()——它关的是整个池,不是当前事务 - 用
defer tx.Rollback()开头,再if err == nil { tx.Commit() },避免忘记 commit 导致连接卡在 idle in transaction
扫描 NULL 值必须用指针或 sql.NullXXX,否则 panic
PostgreSQL 的 NULL 到 Go 默认映射为零值,但结构体字段是值类型时,Scan 会直接 panic:sql: Scan error on column index 2: unsupported Scan, storing driver.Value type <nil> into type *string</nil>。
- 字段类型用
*string/*int64等指针,或sql.NullString/sql.NullInt64 -
pgx支持自定义类型扫描(比如pgtype.Text),但除非你明确需要处理UNKNOWN状态,否则优先用标准sql.NullXXX - 用
struct扫描时,别依赖字段顺序,老老实实用rows.Scan(&u.ID, &u.Name, &u.Email)显式对应,避免加字段后错位
pg_stat_activity 和应用侧连接池指标看,光看日志没用。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










