Go/Golang sql.DB 在函数中重用

sql.Open() 返回一个 *sql.DB 类型的变量

我有一个函数可以调用 10 个其他函数,这些函数都需要进行数据库调用

是否更正确/有效:

  • 将 *sql.DB 指针发送到每个函数,或

  • 在每个函数中创建一个新的 *sql.DB 对象

意义

func DoLotsOfThings() {

    db, _ := sql.Open()

    defer db.Close()

    DoTask1(db)

    DoTask2(db)

}

或者


func DoLotsOfThings() {

    DoTask1()

    DoTask2()

}


func DoTask1() {

    db, _ := sql.Open()

    defer db.Close()

}


func DoTask1() {

    db, _ := sql.Open()

    defer db.Close()

}

我问的原因是因为我目前正在向每个函数发送指针,而我的驱动程序似乎坏了。我正在使用http://code.google.com/p/odbc,这让我相信每个功能都应该有自己的功能,并且我可以依赖驱动程序的内部结构。


编辑


RE 驱动程序破损,仅在高流量环境下才会发生。它只发生在说,十分钟左右的时间之后。这让我相信存在某种内存泄漏导致驱动程序停止工作。但是,我为 *sql.DB 的每个实例推迟了 db.Close(),所以我不知道我还能做些什么来解决这个问题。


andybalholm 说连接池是在内部处理的,这似乎是准确的,因为它只会在我尝试执行某些操作后中断,而不是在我调用 sql.Open() 时中断


如果我让 Go 应用程序运行,它将无法执行任何类型的 SQL 查询,但是如果我尝试单独运行其他 Go 测试,连接到 MSSQL 并运行查询,它就可以工作。


Helenr
浏览 182回答 2
2回答

ABOUTYOU

您不需要到处打开数据库连接。database/sql 包在内部进行连接池,根据需要打开和关闭连接,同时提供可以并发使用的单个连接的错觉。可能您需要在别处寻找驱动程序损坏的原因。关于这方面的更多细节将使人们更容易弄清楚发生了什么。

蝴蝶不菲

var db *sql.DB全局声明一个,然后在您的代码中重用它。这是一个示例(简化):var db *sql.DBfunc DoLotsOfThings() {    DoTask1(db)    DoTask2(db)}func main() {  db, _ = sql.Open() # or whatever you use  defer db.Close()  DoLotsOfThings()}*sql.DB全局声明还有一些额外的好处,例如SetMaxIdleConns(调节连接池大小)或在应用程序中准备SQL 语句。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go