【发布时间】:2022-05-09 19:34:52
【问题描述】:
我正在开发的 api 遇到一些问题:有时(是的,并非总是如此)当我从我的 Angular 应用程序向 golang 服务器发出请求时,它给了我这个错误:“sql: database is closed " 当我试图执行“QueryContext”时,但我认为它更频繁地发生在从数据库请求更大数据的函数上(200 条记录顶部)。
有没有办法检查连接是否仍然打开\有效? golang的连接池不应该自动做吗? (我在具有相同数据库的同一服务器中还有其他更“轻”的 API,并且一切正常)
有什么我应该改变的MySql设置吗?(mysql有默认设置)
golang 版本:1.16, mysql 8.0.17
Hre 是我的代码示例: 在包 database.go 上
func OpenConnection() (*sql.DB, error)
{
connection, err = sql.Open("mysql", "root@/my_database")
if err != nil {
log.Println("Error opening the connection with the database")
return nil, err
}
return connection, nil
}
在 main.go 上
func main() {
---
http.HandleFunc("/apicall1", customFunc)
http.HandleFunc("/apicall2", customFunc)
http.HandleFunc("/apicall3", customFunc)
}
func customFunc(w http.ResponseWriter, r *http.Request) {
conn, err := database.OpenConnection()
if err != nil {
//handle error 500 response
}
defer conn.Close()
switch(r.URL.Path) {
case "url1": my_package.Func1(conn)
case "url2": my_package.Func2(conn)
case "url3": my_package.Func3(conn)
...
default: //handle not found response
}
}
【问题讨论】:
-
你的 Go 代码在哪里?
-
Matteo 你打开了太多的连接。您的应用程序通常应该只打开一个
*sql.DB并在应用程序的整个生命周期中使用它。即在每个处理程序中为每个请求调用 OpenConnection 是 bad。 stackoverflow.com/questions/50787804/… -
sql.Open上的文档说:“返回的 DB 对于多个 goroutine 并发使用是安全的,并维护自己的空闲连接池。因此,Open 函数应该是只调用一次。很少需要关闭数据库。" -
但是!您必须
Close每个返回的*sql.Rows。您必须Scan每个返回的*sql.Row。您必须Commit或Rollback每个*sql.Tx。而且你必须Close每一个*sql.Stmt你不会再使用。 -
好的,所以我必须在 http.HandleFunc 之前移动 main func 中的开口。对于 *sql.Rows 和其他所有内容,我肯定会关闭它,但我会检查