在Go中关闭数据库连接的更好/更短的方法

时间:2015-01-21 02:19:08

标签: database go

通常我会写这样的东西

rows := db.MyPgConn.QueryRows(`SELECT * FROM bla`) // or any other query
for rows.Next() { // if there are result
   // rows.Scan( 
   // do custom operation
}
rows.Close() // close recordset

但是这样,有可能我忘记编写rows.Close(),就像这个code那样可以使可用连接/套接字的数量耗尽,有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

为此目的完全引入defer

rows := db.MyPgConn.QueryRows(`SELECT * FROM bla`) // or any other query
defer rows.Close()

for rows.Next() { // if there are result
   // rows.Scan( 
   // do custom operation
}

来自文档:

  

推迟对Close等函数的调用有两个好处。首先,它保证您永远不会忘记关闭文件,如果您稍后编辑函数以添加新的返回路径,则很容易犯这个错误。其次,这意味着关闭位于开放附近,这比将其放置在功能的末尾要清晰得多。

答案 1 :(得分:1)

正如Intermernet所提到的,defer语句是使close语句更接近于声明rows var的最佳方法。我能想到的唯一方法可能是缩短或更简单,就是在数据库调用周围创建一个包装函数。

func performQuery(q string, op func(db.rows)) {
    rows := db.MyPg.Conn.QueryRows(q)
    // defer rows.Close()
    op(rows)
    rows.Close()
}

// then we could do:
performQuery(`SELECT * FROM bla`,func(rows db.Rows) {
  for rows.Next() {
    // rows.Scan(      
  }
})

然而,这会限制您使用参数进行查询(例如SELECT * FROM tableName WHERE id = $1