【问题标题】:When should I close the database connection in this simple web app?我应该什么时候关闭这个简单的 Web 应用程序中的数据库连接?
【发布时间】:2015-06-21 06:38:50
【问题描述】:

我正在编写一个使用 PostgreSQL 的简单 Go Web 应用程序。我的main 函数看起来像

var db *sql.DB

func main() {
    var err error
    db, err = sql.Open("postgres", "...")
    if err != nil {
        log.Fatalf("Couldn't connect to the database: %v", err)
    }

    http.HandleFunc("/whatever", whateverHandler)
    http.ListenAndServe("127.0.0.1:8080", nil)
}

似乎我应该在某个时候在数据库连接上调用Close(),但是什么时候?这个应用程序永远服务(即直到我用^C 杀死它)。如果我在ListenAndServe 调用之后添加代码,它不会运行,因为我的^C 已经杀死了整个应用程序。我的应用程序应该采用不同的结构吗?

【问题讨论】:

  • 正如 Elwinar 所说,在这种情况下,这并不重要,但通常您将 defer foo.Close() 放在您打开的任何资源之后。否则,您可能会忘记稍后致电Close

标签: go


【解决方案1】:

在这种特殊情况下,我倾向于说你甚至不需要费心:程序结束时连接将被关闭,所以你不会泄漏任何东西。

如果你真的需要正确关闭东西,更简单的选择是使用graceful服务器,defer资源关闭。

或者,如果您的用例更复杂,请通过捕获 signals 并以您自己的方式优雅地关闭(例如使用关闭通道)手动完成。

【讨论】:

  • 太棒了。我是 Go 新手,我不清楚即使应用程序被终止,连接也会关闭。
  • 请注意,在数据库连接的情况下,db.Close 整个池对您来说并不是超级关键。否则在实际调用os.Exit 之前捕获信号(SIGTERM)并运行它可能是“最安全”的方式。如果您刚刚开始,请不要为此分心。
【解决方案2】:

了解sql.Open() 不会打开与数据库的连接很重要...http://golang.org/pkg/database/sql/#Open

Open 可能只是验证其参数而不创建与数据库的连接。要验证数据源名称是否有效,请调用 Ping。

了解驱动程序处理连接维护也很重要。因此,您可能希望在应用程序的整个生命周期内保持打开状态。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-08
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多