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

在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 {
            ...
        }
    }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题