使用 `defer rows.close()` 是 go 中确保数据库结果集及时释放的标准做法,能有效避免连接泄漏,提升程序稳定性与可维
护性。
在 Go 的数据库操作中,*sql.Rows 对象代表查询结果集,其底层持有数据库连接资源。若未显式调用 rows.Close(),该连接将无法归还至连接池,长期积累会导致“too many connections”错误或 socket 耗尽,尤其在高并发场景下风险显著。
最简洁、可靠且符合 Go 惯例的解决方案是 在获取 rows 后立即使用 defer 延迟关闭:
rows, err := db.Query("SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
log.Fatal(err)
}
defer rows.Close() // ✅ 保证函数退出前必执行,无论是否发生 panic 或提前 return
for rows.Next() {
var id int
var name string
if err := rows.Scan(&id, &name); err != nil {
log.Printf("scan error: %v", err)
continue // 或 break / return,defer 仍会执行
}
fmt.Printf("User %d: %s\n", id, name)
}
// 注意:此处无需再写 rows.Close()
if err := rows.Err(); err != nil {
log.Printf("iteration error: %v", err)
}✅ 关键优势:
⚠️ 注意事项:
总结:defer rows.Close() 不仅是更短的写法,更是 Go 资源管理哲学的体现——“打开即承诺关闭”。养成这一习惯,可大幅降低数据库连接泄漏风险,让代码更健壮、更易维护。