dongni8969 2019-04-24 12:01
浏览 194
已采纳

在golang项目中的sqlx上查询后,数据库连接仍在使用中

I'm working in a golang project using sqlx and postgres. When the application starts I open a connection with the database and use it like this:

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
}

The problem is that in some blocks of code the connection still in use, here one example:

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.")
...
            }

When I try test it doing something like it, the test don't open many connections. Here some test code:

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!!")

Some time I get max connections and the application die.

  • 写回答

1条回答 默认 最新

  • duansha6410 2019-05-16 17:12
    关注

    Thanks to @mkopriva ! I still don't know why the connections still in use, but to solve my problem I've use Tx and create a function to defer a commit or a rollback (commit and rollback both return a error, I was having problems to close the connections because that - in the Tx cases):

    func commitORRollback(db *sqlx.Tx, ROLLBACK *bool) {
        if *ROLLBACK {
            if err := db.Rollback(); err != nil {
                ...
            }
        } else {
            ...
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误