数据库连接最佳实践

wey*_*y23 6 go

我有一个使用net/http的应用程序.我注册了一些带有http的处理程序,需要从数据库中获取一些东西才能继续编写响应并完成请求.

我的问题是关于连接到这个数据库的最佳实践.我希望这可以每分钟一个请求或每秒10个请求.

每次请求进入时,我都可以连接到每个处理程序中的数据库.(这会为每个请求产生一个到mysql的连接?)

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "net/http"
    "fmt"
)

func main() {

    http.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) {
        db, err := sql.Open("mysql","dsn....")
        if err != nil {
            panic(err)
        }
        defer db.Close()

        row := db.QueryRow("select...")
        // scan row

        fmt.Fprintf(w,"text from database")
    })

    http.ListenAndServe(":8080",nil)
}
Run Code Online (Sandbox Code Playgroud)

我可以在app start连接到数据库.每当我需要使用数据库时,我就Ping它,如果它关闭了,我就重新连接它.如果它没有关闭,我继续使用它.

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "net/http"
    "fmt"
    "sync"
)

var db *sql.DB
var mutex sync.RWMutex

func GetDb() *sql.DB {

    mutex.Lock()
    defer mutex.Unlock()

    err := db.Ping()
    if err != nil {
        db, err = sql.Open("mysql","dsn...")
        if err != nil {
            panic(err)
        }
    }

    return db
}

func main() {

    var err error
    db, err = sql.Open("mysql","dsn....")
    if err != nil {
        panic(err)
    }

    http.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) {

        row := GetDb().QueryRow("select...")
        // scan row

        fmt.Fprintf(w,"text from database")
    })

    http.ListenAndServe(":8080",nil)
}
Run Code Online (Sandbox Code Playgroud)

哪种方式最好,还是有另一种方式更好.让多个请求使用相同的数据库连接是一个坏主意吗?

我很不情愿地创建一个运行到mysql连接限制的应用程序,但我不想忽略这个限制的事实.

Elw*_*nar 7

最好的方法是在应用启动时创建一次数据库,然后使用此句柄.另外,该sql.DB类型对于并发使用是安全的,因此您甚至不需要互斥锁来锁定它们的使用.最后,根据您的驱动程序,数据库句柄将自动重新连接,因此您不需要自己重新连接.

  • 正常操作期间不需要调用 db.Close()。sql.DB 已经可以安全地用作全局变量,因此*不要*添加您自己的互斥体。 (3认同)