Golang: Database: database/sql: sql.DB Object

15th December 2021 at 12:01pm

sql.DB 是这套体系中的顶层对象,可以通过 sql.Open() 函数获得:

db, err := sql.Open("pgx", connectionString)

它不代表一个数据库连接;它仅代表一个数据库实体,不管它是通过 TCP 连接的,还是本地文件亦或放在内存中。它的职责是:

  • 通过数据库 driver 打开和关闭与数据库的连接
  • 维护连接池

实际的连接会 lazily 发生在有查询等操作时。

设计文档中提到:

Handle concurrency well. Users shouldn’t need to care about the database’s per-connection thread safety issues (or lack thereof), and shouldn’t have to maintain their own free pools of connections. The ‘sql’ package should deal with that bookkeeping as needed. Given an *sql.DB, it should be possible to share that instance between multiple goroutines, without any extra synchronization.

sql.DB 并不是设计用来频繁 Open()Close() 的。它屏蔽了底层连接管理,使得用户不用去自己维护连接池;并且可以在不同的 go routine 间共享,而不需要使用额外的同步机制。

DB 的 接口文档 提到:

DB is a database handle representing a pool of zero or more underlying connections. It’s safe for concurrent use by multiple goroutines.

The sql package creates and frees connections automatically; it also maintains a free pool of idle connections. If the database has a concept of per-connection state, such state can be reliably observed within a transaction (Tx) or connection (Conn). Once DB.Begin is called, the returned Tx is bound to a single connection. Once Commit or Rollback is called on the transaction, that transaction’s connection is returned to DB’s idle connection pool. The pool size can be controlled with SetMaxIdleConns.