在多线程应用程序中使用 gorm 的最佳方式是什么?

What is the best way to use gorm in multithreaded application?

我有一个打开很多例程的应用程序。让我们说2000个例程。每个例程都需要访问数据库,或者至少需要 update/select 来自数据库的数据。

我目前的做法如下:

Routine gets *gorm.DB with db.GetConnection(), 这是这个函数的代码:

func GetConnection() *gorm.DB {
    DBConfig := config.GetConfig().DB
    db, err := gorm.Open("mysql", DBConfig.DBUser+":"+DBConfig.DBPassword+"@/"+DBConfig.DBName+"?charset=utf8mb4")
    if err != nil {
        panic(err.Error())
    }
    return db
}

然后例程从一些存储包中调用另一个函数并将 *gorm.DB 传递给函数并关闭连接,它看起来像这样:

dbConnection := db.GetConnection()
postStorage.UpdateSomething(dbConnection)
db.CloseConnection(dbConnection)

以上只是例子,主要思想是每个例程都打开新连接,我不喜欢它。因为它可能会使数据库过载。结果我得到了下一个 MySQL 错误:

[mysql] 2020/07/16 19:34:26 packets.go:37: read tcp 127.0.0.1:44170->127.0.0.1:3306: read: connection reset by peer

问题是关于如何在多例程应用程序中使用 gorm 包的良好模式?

*gorm.DB 是多线程安全的,您可以在多个例程中使用一个 *gorm.DB。您可以初始化一次并随时获取它。演示:

package db

var db *gorm.DB

fund init() {
    DBConfig := config.GetConfig().DB
    db, err := gorm.Open("mysql", DBConfig.DBUser+":"+DBConfig.DBPassword+"@/"+DBConfig.DBName+"?charset=utf8mb4")
    if err != nil {
        panic(err.Error())
    }
}

func GetConnection() *gorm.DB {
    return db;
}