如何处理Go应用中的Db连接打开/关闭?

Ser*_*rov 4 postgresql go

我的Web API应用程序中有一组功能。他们对Postgres数据库中的数据执行一些操作。

func CreateUser () {
    db, err := sql.Open("postgres", "user=postgres password=password dbname=api_dev sslmode=disable")
    // Do some db operations here
}
Run Code Online (Sandbox Code Playgroud)

我想函数应该彼此独立地与db一起工作,所以现在我sql.Open(...)在每个函数中都有了。我不知道这是管理数据库连接的正确方法。

应用启动后,是否应该在某个地方打开它,并将db作为参数传递给相应的函数,而不是在每个函数中都打开连接?

icz*_*cza 6

每次需要时打开数据库连接都是浪费资源,而且速度很慢。

相反,您应该sql.DB在应用程序启动时(或在首次请求时)创建一次,然后将其传递到需要的地方(例如,作为函数参数或通过某些上下文),或者只是将其设置为全局变量,这样每个人都可以访问它。从多个goroutine调用是安全的。

引自以下文档sql.Open()

返回的数据库可安全地供多个goroutine并发使用,并维护其自己的空闲连接池。因此,Open函数应仅被调用一次。很少需要关闭数据库。

您可以使用包init()函数对其进行初始化:

var db *sql.DB

func init() {
    var err error
    db, err = sql.Open("yourdriver", "yourDs")
    if err != nil {
        log.Fatal("Invalid DB config:", err)
    }
}
Run Code Online (Sandbox Code Playgroud)

这里要注意的一件事是,sql.Open()可能不会创建与数据库的实际连接,而可能只是验证其参数。要测试您是否可以真正连接到数据库,请使用DB.Ping(),例如:

func init() {
    var err error
    db, err = sql.Open("yourdriver", "yourDs")
    if err != nil {
        log.Fatal("Invalid DB config:", err)
    }
    if err = db.Ping(); err != nil {
        log.Fatal("DB unreachable:", err)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @GujaratSantana是的,强烈建议不要一直关闭并重新打开数据库连接。如果数据库更改(例如,数据库名称,主机或身份验证信息更改),则只需关闭数据库连接。或者当您的应用退出时。 (2认同)