一个mysql连接应该在golang中存在多长时间

时间:2015-04-10 10:05:27

标签: mysql go

我正在使用golang和阅读这个doc的mysql。它说

  

虽然在完成数据库时Close()数据库是惯用的,但sql.DB对象的设计是长期存在的。不经常打开()和关闭()数据库。

我不知道连接应该持续多久。现在,如有必要,我会打开每个http请求的连接。太频繁了吗?

2 个答案:

答案 0 :(得分:13)

在同一份文件中进一步说明:

  

相反,为您需要访问的每个不同数据存储创建一个sql.DB对象,并保持该对象直到程序完成访问该数据存储。根据需要传递它,或者以某种方式在全球范围内提供它,但保持打开状态。并且不要从短期函数中打开()和关闭()。相反,将sql.DB作为参数传递给该短期函数。

     

如果不将sql.DB视为长期存在的对象,则可以   遇到诸如重用不良和连接共享等问题,   耗尽可用的网络资源,或者由于偶发的故障   许多TCP连接仍处于TIME_WAIT状态。这样   问题是你没有使用数据库/ sql的迹象   设计的。

打开和关闭数据库连接是一项代价高昂的操作,因此您希望尽可能避免这种情况。你肯定不希望在每次请求后关闭连接(除非每天只有几个,即使这样,只要应用程序运行,你就可以保持打开状态)

数据库/ sql包使用了connection pooling,因此您不必担心管理多个连接。

答案 1 :(得分:7)

没有权威的答案,因为它取决于您使用的驱动程序。如果你使用的是:

...那么你根本不应该关闭你的sql.DB。这些情况下的sql.DB代表连接池,并且在处理程序/请求/函数中使用它意味着您只是使用该池中的连接(如果可用)。

e.g。

var db *sql.DB

func setup() error {
    var err error
    db, err = sql.Open(...)
    if err != nil {
        log.Fatal(err)
    }

    // Other setup-related activities
}

func main()
    err := setup()
    if err != nil {
        log.Fatal(err)
    }

    // No need to call `defer db.Close()` here
    http.ListenAndServe(...)
}

func SomeHandler(w http.ResponseWriter, r *http.Request) {
    u := User{}
    res, err := db.GetThings(&u)
    // No need to close this here - it's just a connection dynamically pulled
    // from our sql.DB connection pool in most cases
}