GO SQL.CONN 总是卡在 conn.Close()

问题描述 投票:0回答:1

go
中,我遇到了
sql.DB
的连接池堆积了如此多的连接,以至于达到了odbc驱动程序的限制的问题。连接应该自动关闭,但这永远不会发生。

所以我想看看当我专门请求连接、执行查询并最终关闭它以将其返回到池时会发生什么。 以下代码卡在最后的

err = conn.Close()
行。有人能弄清楚为什么吗?


package main

import (
    "database/sql"
    "log"

    "github.com/gin-gonic/gin"
)

var db *sql.DB

func main() {
    db, err := sql.Open("odbc", "DSN=ADSconnStr")
    if err != nil {
        log.Fatal(err)
        return
    }
    
    err = db.Ping()
    if err != nil {
        log.Fatal(err)
        return
    }
    
    router := gin.Default()
    router.GET("test/url", testQuery)
    log.Fatal(router.Run(":8080"))

    err = db.Close()
    if err != nil {
        log.Fatal(err)
    }
}

func testQuery(c *gin.Context) {

    ctx := c.Copy()
    conn, err := db.Conn(ctx)
    if err != nil {
        log.Fatal(err)
        return
    }

    rows, err := conn.QueryContext(ctx, "SELECT * FROM testTable;")
    if err != nil {
        log.Fatal(err)
        return
    }

    // scan results ...

    err = rows.Close()
    if err != nil {
        log.Fatal(err)
        return
    }

    // here it gets stuck. conn.Close never returns
    err = conn.Close()
    if err != nil {
        log.Fatal(err)
        return
    }
}

go odbc advantage-database-server
1个回答
0
投票

我发现了问题:

sql.Open("odbc", "DSN=ADSconnStr")
中,我建立了与旧 sql 数据库管理系统(Advantage Database Server)的连接。这个 DBMS 具有这样的“功能”,只要还存在任何(缓存的?)对象,它就可以强烈地让您不会断开连接。即>准备好的报表<. They must be closed.

以下代码有效。也许可以缩短它,但我明确想关闭连接。

func testADS(c *gin.Context) {
    conn, err := db.Conn(context.Background())
    if err != nil {
        log.Panic("no connection")
    }

    tx, err := conn.BeginTx(context.Background(), nil)
    if err != nil {
        log.Panic("no transaction")
    }

    stmt, err := tx.Prepare("SELECT some_code FROM testTable")
    if err != nil {
        log.Panic("no prepared statement")
    }

    rows, err := stmt.Query()
    if err != nil {
        log.Panic("no rows")
    }

    if !rows.Next() {
        log.Panic("no next row")
    }

    var code string
    err = rows.Scan(&code)
    if err != nil {
        log.Panic("no scan")
    }

    log.Printf("Code: %s", code)

    err = tx.Commit()
    if err != nil {
        log.Panic("no commit")
    }

    err = rows.Close()
    if err != nil {
        log.Panic("no rows close")
    }

    err = stmt.Close()
    if err != nil {
        log.Panic("no stmt close")
    }

    // now that the statement is closed the connection can be closed finally 
    err = conn.Close()
    if err != nil {
        log.Panic("no conn close")
    }

    // log.Celebrate("Yay :)") 
}
© www.soinside.com 2019 - 2024. All rights reserved.