使用database/sql连接PostgreSQL/MySQL前必须安装对应驱动并下划线导入,sql.Open仅初始化连接池不校验连接,需调用db.Ping()验证;连接池参数默认无限制,须显式设置SetMaxOpenConns等避免线上问题;事务中所有操作必须通过*sql.Tx执行。

用 database/sql 连 PostgreSQL / MySQL 前必须装驱动
Go 标准库的 database/sql 是接口层,不带具体数据库实现。直接 import "database/sql" 后调用 sql.Open 会 panic:「sql: unknown driver "postgres"」或「unknown driver "mysql"」。
- PostgreSQL:必须
go get github.com/lib/pq(注意不是github.com/libpq),然后在代码里import _ "github.com/lib/pq"(下划线导入触发 init) - MySQL:推荐
go get github.com/go-sql-driver/mysql,导入写法同上:import _ "github.com/go-sql-driver/mysql" - SQLite3:用
go get github.com/mattn/go-sqlite3,注意它依赖 C 编译器,Windows 用户需提前装好 MinGW 或 TDM-GCC
sql.Open 不真正连数据库,db.Ping() 才校验连接有效性
sql.Open 只是初始化连接池配置,返回 *sql.DB 对象。即使传了错误的 host 或 port,也不会报错。常见误判是以为 sql.Open 失败就代表连不上。
- 正确做法:调用
db.Ping()(同步阻塞)或db.PingContext(ctx)(支持超时) - 连接字符串格式要严格:PostgreSQL 是
"host=localhost port=5432 user=xxx password=xxx dbname=xxx sslmode=disable";MySQL 是"user:password@tcp(127.0.0.1:3306)/dbname" - 如果
Ping()报错,检查是否漏了驱动导入、端口被占、防火墙拦截,或数据库服务根本没启动
连接池参数不设默认值容易拖垮服务
Go 的 *sql.DB 自带连接池,但 SetMaxOpenConns、SetMaxIdleConns、SetConnMaxLifetime 全部默认为 0(即无限制或无限期),线上环境极易引发数据库连接数爆满、连接复用失效、TIME_WAIT 堆积等问题。
-
db.SetMaxOpenConns(20):控制最大并发连接数,建议设为数据库侧max_connections的 70% 左右 -
db.SetMaxIdleConns(10):空闲连接上限,避免长期闲置连接占用资源 -
db.SetConnMaxLifetime(30 * time.Minute):强制连接在池中存活不超过 30 分钟,防止因数据库重启或网络中断导致 stale connection
事务里别混用 db.Query 和 tx.Query
开启事务后,所有 SQL 操作必须通过 *sql.Tx 对象执行,不能继续用原始 *sql.DB。否则语句不会受事务控制,tx.Commit() 或 tx.Rollback() 对它们完全无效。
PHP商城系统是国内领先商城系统,网店系统,购物系统,网上商城系统,B2C商城系统产品.同时也是一个商业的PHP开发框架。PHP 商城系统由内容、文章、会员、留言、订单、 财务、广告、短消息、数据库管理、营销推广、内置支付管理、商品配送管理、无限级分类、全站搜索等多个功能模块插件组成。在当今瞬机万变的市场环境中,快速高效的IT解决方案是您业务成功的关键。我们PHP商城系统能为您量身打造完全符合需求
立即学习“go语言免费学习笔记(深入)”;
- 错误写法:
tx, _ := db.Begin() _, _ := db.Query("INSERT ...") // 这条不在事务里! tx.Commit() - 正确写法:
tx, _ := db.Begin() _, _ := tx.Query("INSERT ...") // 必须用 tx.Query / tx.Exec / tx.Prepare if err != nil { tx.Rollback() return } tx.Commit() - 注意:事务对象不可复用,
tx.Commit()后再调用tx.Query会 panic:「sql: transaction has already been committed or rolled back」
实际项目中,最容易被忽略的是连接池参数和事务作用域边界——它们不会立刻报错,但会在高并发或长时间运行后突然暴露问题。









