本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《在golang项目中查询sqlx后数据库连接仍在使用》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
问题内容
我正在一个使用 sqlx 和 postgres 的 Golang 项目中工作。当应用程序启动时,我打开与数据库的连接并按如下方式使用它:
var connro *sqlx.db
var connrw *sqlx.db
...
/ getinstance - will return the connection opened to the database
func getinstance(readonly bool) *sqlx.db {
if readonly {
return connro
}
return connrw
}
问题是在某些代码块中连接仍在使用中,这里是一个示例:
instancerw := database.getinstance(false)
instancero := database.getinstance(true)
...
err := instancero.get(&idfuncionario, `
select id
from t_funcionario
where codigo_externo = $1 `,
i.funcionarioid)
if err != nil {
log.println(err)
return errors.new("erro ao identificar funcionário.")
}
// verifica se o item é granel
// caso não seja
if *i.itemgranelid == 0 {
// verifica se o item está disponível
err = instancero.get(&localidade_id, `
select coalesce(localidade_id, 0)
from t_item
where id = $1
`, i.itemid)
if err != nil {
log.println(err)
return errors.new("não foi possível identificar tipo do item.")
...
}
当我尝试测试它做类似的事情时,测试不会打开很多连接。这里是一些测试代码:
i := 600
for i != 0 {
if true {
err := db.Select(&item, `SELECT * FROM t_item LIMIT 10`)
if err != nil {
}
err = db.Select(&categoria, `SELECT * FROM t_categoria LIMIT 10`)
if err != nil {
}
err = db.QueryRow(`INSERT INTO t_categoria
(
nome,
ativo
)
VALUES ($1, $2)`, fmt.Sprintf("cateToTeste%v", i), true).Scan(&itemget)
if err != nil {
}
err = db.Get(&itemget, `SELECT COALESCE(localidade_id, 0)
FROM t_item
WHERE id = $1`, 150)
if err != nil {
}
log.Println("ok")
i--
}
}
log.Println("Tudo ok!!")
有时我获得最大连接数,但应用程序崩溃了。
解决方案
感谢@mkopriva! 我仍然不知道为什么连接仍在使用中,但为了解决我的问题,我使用 tx 并创建一个函数 defer a commit 或 rollback (提交和回滚都返回错误,我在关闭时遇到问题连接,因为 - 在 tx 情况下):
func commitORRollback(db *sqlx.Tx, ROLLBACK *bool) {
if *ROLLBACK {
if err := db.Rollback(); err != nil {
...
}
} else {
...
}
}
今天带大家了解了的相关知识,希望对你有所帮助;