Соединения с базой данных все еще используются после запроса на sqlx в проекте golang - PullRequest
0 голосов
/ 24 апреля 2019

Я работаю в проекте golang, используя sqlx и postgres.Когда приложение запускается, я открываю соединение с базой данных и использую его следующим образом:

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

Некоторое время я получаю максимальное количество подключений и приложение умирает.

1 Ответ

0 голосов
/ 16 мая 2019

Благодаря @mkopriva! Я до сих пор не знаю, почему соединения все еще используются, но для решения моей проблемы я использую Tx и создаю функцию для defer a commit или rollback (commit и rollback оба возвращают ошибку У меня были проблемы с закрытием соединений, потому что - в случаях Tx:

func commitORRollback(db *sqlx.Tx, ROLLBACK *bool) {
    if *ROLLBACK {
        if err := db.Rollback(); err != nil {
            ...
        }
    } else {
        ...
    }
}
...