在 golang 项目中查询 sqlx 后数据库连接仍在使用中
Database connections still in use after query on sqlx in a golang project
我在一个使用 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 = `,
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 =
`, 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 (, )`, 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 = `, 150)
if err != nil {
}
log.Println("ok")
i--
}
}
log.Println("Tudo ok!!")
有时我达到最大连接数,应用程序死机了。
感谢@mkopriva!
我仍然不知道为什么连接仍在使用中,但为了解决我的问题,我使用了 Tx
并创建了一个函数到 defer
a commit
或 rollback
(提交和回滚都是 return 错误,我在关闭连接时遇到问题,因为 - 在 Tx
情况下):
func commitORRollback(db *sqlx.Tx, ROLLBACK *bool) {
if *ROLLBACK {
if err := db.Rollback(); err != nil {
...
}
} else {
...
}
}
我在一个使用 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 = `,
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 =
`, 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 (, )`, 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 = `, 150)
if err != nil {
}
log.Println("ok")
i--
}
}
log.Println("Tudo ok!!")
有时我达到最大连接数,应用程序死机了。
感谢@mkopriva!
我仍然不知道为什么连接仍在使用中,但为了解决我的问题,我使用了 Tx
并创建了一个函数到 defer
a commit
或 rollback
(提交和回滚都是 return 错误,我在关闭连接时遇到问题,因为 - 在 Tx
情况下):
func commitORRollback(db *sqlx.Tx, ROLLBACK *bool) {
if *ROLLBACK {
if err := db.Rollback(); err != nil {
...
}
} else {
...
}
}