0

我的代码是这样设置的,每次我想进行查询时,我都会打开数据库,运行 QueryRow(),将结果扫描到变量中,然后使用 defer 关闭数据库和行。但是,尽管我相信我已经将它们全部关闭,但我遇到了连接泄漏。

我已经尝试将关闭语句从延迟中取出,在我完成使用它时关闭它们。我遵循了如何在 Go 中为行插入重用单个 Postgres DB 连接?但是尽管我相信我正在遵循答案,但仍然没有运气。

func (a AccessPostgres) OpenDB() (*sql.DB, error) {
    dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
                            user, password, a.DBName)

    var err error

    db, err := sql.Open("postgres", dbinfo)
    if err != nil {
        return nil, err
    }

    return db, nil
}

func (a AccessPostgres) Run(s string) error {
    db, err := a.OpenDB()
    if err != nil {
        return err
    }
    defer db.Close()

    _, err = db.Exec(s)
    if err != nil {
        return err
    }

    return nil
}

type Row struct {
    Collection_time string
    Dbid            string
    Hostname        string
    Dbname          string
    Name            string
    Value           string
}

type QueryResult struct {
    Rows  []Row
}

func (a AccessPostgres) Query(q string) ([]byte, error) {

    db, err := a.OpenDB()
    if err != nil {
        return nil, err
    }
    defer db.Close()

    rows, err := db.Query(q)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var qr QueryResult
    for rows.Next() {
        var r Row
        err := rows.Scan(&r.Collection_time, &r.Dbid, &r.Hostname, &r.Dbname, &r.Name, &r.Value)
        if err != nil {
            return nil, err
        }
        qr.Rows = append(qr.Rows, r)
    }


    result, err := json.Marshal(qr)
    if err != nil {
        return nil, err
    }

    return result, nil
}

在大多数情况下,事情运作良好。但是这段代码会间隔运行,一段时间后会出现“pq:抱歉,客户端太多”错误。这就是发生的一切。

4

0 回答 0