pgx连接cockroachdb需显式配置ssl模式或证书:本地--insecure时加?sslmode=disable;启用tls时须指定sslrootcert并设sslmode=verify-full;务必使用pgxpool连接池而非每次handler中connect();insert...returning和on conflict必须用queryrow()/query();事务中需defer tx.rollback(ctx)并在commit成功后取消;set transaction priority仅影响冲突裁决。

pgx 连接 CockroachDB 时 URL 格式要加 ?sslmode=disable 或配证书
默认情况下,CockroachDB 启动后强制要求 TLS(即使本地开发用 cockroach start --insecure),而 pgx 默认走 sslmode=require,结果一连就报错:dial tcp [::1]:26257: connect: connection refused 或更隐蔽的 failed to connect to `host=localhost user=root database=bank`: server error (FATAL: SSL is required)。
解决方法很简单,但容易卡住:在连接字符串末尾显式关闭 SSL 检查——前提是确认你用的是 --insecure 模式;如果启用了 TLS(比如生产环境),就得提供 CA 证书路径。
- 本地开发(
cockroach start --insecure):连接串写成postgresql://root@localhost:26257/defaultdb?sslmode=disable - 启用 TLS 的集群:必须加
sslrootcert=/path/to/ca.crt,且sslmode改为verify-full或require -
pgx.ParseConfig()里手动设Config.TLSConfig = nil也能绕过,但不推荐——不如直接改 URL 清晰
用 pgx.Connect() 还是 pgxpool.Connect()?别在 HTTP handler 里单次 Connect()
CockroachDB 是分布式系统,连接建立本身有开销,而且 pgx.Connect() 返回的是单次连接,用完不关会泄漏;HTTP handler 里每次请求都 Connect() + Close(),轻则慢,重则触发连接数上限(CockroachDB 默认 max_connections=100)。
正确做法是复用连接池。CockroachDB 对连接池友好,pgxpool 能自动处理健康检查、连接重建和超时驱逐。
立即学习“go语言免费学习笔记(深入)”;
- 初始化一次全局
*pgxpool.Pool,例如在main()里调用pgxpool.Connect(context.Background(), connString) - handler 中直接用
pool.Query()或pool.Exec(),不用管打开/关闭 - 注意设置合理
max_conns:CockroachDB 推荐每节点 100–200 连接,Go 服务端按并发量配,比如pgxpool.ConnectConfig里设MaxConns: 50
CockroachDB 的 INSERT ... RETURNING 和 ON CONFLICT 在 pgx 里要用 QueryRow() 或 Query()
CockroachDB 兼容 PostgreSQL 语法,但有些惯用法在 pgx 里容易写错。比如想插入并返回主键,或做 upsert,不能只用 Exec()——它不返回结果集。
典型错误是写了 pool.Exec(ctx, "INSERT INTO users(name) VALUES($1) RETURNING id", "alice"),结果拿不到 id,因为 Exec() 忽略 RETURNING 子句。
- 带
RETURNING的语句必须用QueryRow()(单行)或Query()(多行),例如:err := pool.QueryRow(ctx, "INSERT INTO users(name) VALUES($1) RETURNING id", "alice").Scan(&id) -
ON CONFLICT DO UPDATE也一样:只要含RETURNING,就不能用Exec() - CockroachDB 不支持
ON CONFLICT DO NOTHING的变体(如ON CONFLICT (col) WHERE ...),这点比 PG 严格,写之前先确认 schema 约束是否匹配
事务中执行 COMMIT 失败时,pgx 不会自动回滚,得靠 defer tx.Rollback(ctx)
CockroachDB 的事务模型是“乐观并发控制”,COMMIT 可能失败(比如遇到写冲突、事务超时),此时 tx.Commit() 返回非 nil error,但事务状态已不可用——你不能再对它做任何操作,包括再次 Commit() 或 Rollback()。
常见错误是只写 if err := tx.Commit(); err != nil { log.Fatal(err) },结果出错后程序挂死或数据不一致。
- 标准写法是:在
Begin()后立刻defer tx.Rollback(ctx),然后在成功时手动tx.Commit()并清掉 defer(用defer func() { if !committed { _ = tx.Rollback(ctx) } }()或更简单地用sql.Tx风格的defer控制 - CockroachDB 的
SET TRANSACTION PRIORITY会影响冲突概率,高优先级事务更可能赢,但别滥用——优先级不是调度权,只是冲突时的裁决依据 - 如果事务里执行了 DDL(如
CREATE TABLE),CockroachDB 要求该事务只能包含一条语句,否则报错cannot execute multiple statements in a transaction that contains DDL
sslmode=disable 和事务里没设 defer Rollback,这两处一错,要么连不上,要么事务卡死又不报错。











