在这个简单的 Web 应用中,应该在什么时候关闭数据库连接?

huangapple go评论69阅读模式
英文:

When should I close the database connection in this simple web app?

问题

我正在编写一个简单的Go Web应用程序,使用PostgreSQL数据库。我的main函数如下所示:

var db *sql.DB

func main() {
    var err error
    db, err = sql.Open("postgres", "...")
    if err != nil {
        log.Fatalf("无法连接到数据库:%v", err)
    }

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

看起来我应该在某个时候调用Close()关闭数据库连接,但是什么时候呢?这个应用程序会一直运行下去(直到我用^C终止它)。如果我在ListenAndServe调用之后放置代码,它不会被执行,因为我的^C终止了整个应用程序。我的应用程序应该有不同的结构吗?

英文:

I’m writing a simple Go web application that uses PostgreSQL. My main function looks like

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)
}

It seems like I should be calling Close() on the database connection at some point, but when? This application serves forever (i.e. until I kill it with ^C). If I put code after the ListenAndServe call it doesn’t get run, because my ^C has killed the entire application. Should my application be structured differently?

答案1

得分: 7

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

如果你真的需要正确关闭事物,更简单的选择是使用一个graceful服务器,并使用defer来关闭资源。

或者,如果你的用例更加复杂,可以通过捕获信号并以自己的方式优雅地关闭(例如使用一个关闭通道)来手动完成。

英文:

In this particular case, I tend to say you don't even need to bother: the connection will be closed when the program end, so you won't leak anything.

If you really need to close things properly, the simpler choice is to use a graceful server, and defer the resources closing.

Or, if your use case is more complicated, do it by hand by catching signals and gracefully shutting down your own way (using a closing channel for example).

答案2

得分: 5

重要的是要理解sql.Open()并不会打开与数据库的连接... http://golang.org/pkg/database/sql/#Open
>Open可能只是验证其参数而不创建与数据库的连接。要验证数据源名称是否有效,请调用Ping。

另外,重要的是要理解驱动程序处理连接的维护。因此,您可能希望在应用程序的整个生命周期内保持连接处于打开状态。
>返回的DB对象可以安全地供多个goroutine并发使用,并且它维护自己的空闲连接池。因此,应该只调用一次Open函数。很少需要关闭DB对象。

英文:

It is important to understand that sql.Open() does not open a connection to the database... http://golang.org/pkg/database/sql/#Open
>Open may just validate its arguments without creating a connection to the database. To verify that the data source name is valid, call Ping.

Also it is important to understand that the driver handles the maintance of connections. So you will likely want to keep it open for the lifetime of your app.
>The returned DB is safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB.

huangapple
  • 本文由 发表于 2015年3月16日 00:29:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/29063123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定