如何在Go应用程序中处理打开/关闭Db连接?

时间:2016-11-14 10:53:18

标签: postgresql go

我的网络API应用中有一组功能。他们对Postgres数据库中的数据执行一些操作。

func CreateUser () {
    db, err := sql.Open("postgres", "user=postgres password=password dbname=api_dev sslmode=disable")
    // Do some db operations here
}

我认为函数应该与db相互独立地工作,所以现在我在每个函数中都有sql.Open(...)。我不知道这是否是管理数据库连接的正确方法。

应用程序启动后我应该在某个地方打开它并将db作为参数传递给相应的函数而不是在每个函数中打开连接吗?

2 个答案:

答案 0 :(得分:4)

每次需要时打开数据库连接都是浪费资源而且速度很慢。

相反,您应该在应用程序启动时(或首次请求时)创建一次sql.DB,并将其传递到需要它的位置(例如,作为函数参数或通过某些上下文),或者只是制作它是一个全局变量,所以每个人都可以访问它。从多个goroutine打电话是安全的。

引自sql.Open()的文件:

  

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

您可以使用包init()函数对其进行初始化:

var db *sql.DB

func init() {
    var err error
    db, err = sql.Open("yourdriver", "yourDs")
    if err != nil {
        log.Fatal("Invalid DB config:", err)
    }
}

这里需要注意的一点是,sql.Open()可能无法与您的数据库建立实际连接,它可能只是验证其参数。要测试您是否可以实际连接到数据库,请使用DB.Ping(),例如:

func init() {
    var err error
    db, err = sql.Open("yourdriver", "yourDs")
    if err != nil {
        log.Fatal("Invalid DB config:", err)
    }
    if err = db.Ping(); err != nil {
        log.Fatal("DB unreachable:", err)
    }
}

答案 1 :(得分:0)

我将使用postgres示例

package main

导入必要的软件包,别忘了postgres驱动程序

import (
  "database/sql"
  _ "github.com/lib/pq" //postgres driver
)

在包范围内初始化您的连接

var db *sql.DB

具有用于连接的初始化功能

func init() {
  var err error
  db, err = sql.open("postgres", "connectionString")
  //connectioString example => 'postgres://username:password@localhost/dbName?sslmode=disable'
  if err != nil {
    panic(err)
  }
  err = db.Ping()
  if err != nil {
    panic(err)
  }
  // note, we haven't deffered db.Close() at the init function since the connection will close after init. you could close it at main or ommit it
}

主要功能

func main() {
defer db.Close() //optional
//run your db functions
}

签出此示例 https://play.golang.org/p/FAiGbqeJG0H