我正在编写一个使用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
已经杀死了整个应用程序。我的申请应该采用不同的结构吗?
答案 0 :(得分:5)
在这种特殊情况下,我倾向于说你甚至不需要打扰:当程序结束时连接将被关闭,所以你不会泄漏任何东西。
如果您确实需要正确关闭事物,更简单的选择是使用graceful服务器,并defer
关闭资源。
或者,如果您的用例更复杂,可以通过捕捉signals并优雅地关闭自己的方式(例如使用关闭渠道)来手动执行。
答案 1 :(得分:5)
了解sql.Open()
无法打开与数据库的连接非常重要... http://golang.org/pkg/database/sql/#Open
Open可以仅在不创建与数据库的连接的情况下验证其参数。要验证数据源名称是否有效,请调用Ping。
同样重要的是要了解驱动程序处理连接的维护。因此,您可能希望在应用的生命周期内保持开放状态。
返回的数据库可以安全地由多个goroutine并发使用,并维护自己的空闲连接池。因此,Open函数应该只调用一次。很少需要关闭数据库。