go 是如何实现多个goroutine共用一个数据库连接资源?

package main

var conn *sql.DB

func main(){
    var err error
    conn,err = sql.Open(xxx)

    for i:=1; i<=10000; i++ {
        go func(){
            //  这里conn 在一定数据量后会出现  nil
            rows, err := conn.Query(xxxxxxx)
            defer rows.Close() 
        }()
    }
}

这种看起来像是连接资源还没释放,同时另一个goroutine 又去取 conn, 然后根本取不到,
这种情况下改如何加锁控制呢?

go db
最佳答案

没有复现,只要 conn.Query() 就会 err,添加 conn.SetMaxOpenConns(num) 即可复用连接

func Test1(t *testing.T) {
    var err error
    dsn := "root:@tcp(localhost:3306)/mysql"
    conn, err := sql.Open("mysql", dsn)
    if err != nil {
        panic(err)
    }
    conn.SetMaxOpenConns(10)

    var wg sync.WaitGroup

    for i := 0; i < 10000; i++ {
        wg.Add(1)
        go func() {
            defer func() {
                wg.Done()
                if r := recover(); r != nil {
                    t.Log("[ERROR]", r)
                }
            }()
            rows, err := conn.Query("SELECT host,user FROM user")
            if err != nil {
                panic(err)
            }
            defer rows.Close()
        }()
    }

    wg.Wait()
}
3年前 评论
讨论数量: 1

没有复现,只要 conn.Query() 就会 err,添加 conn.SetMaxOpenConns(num) 即可复用连接

func Test1(t *testing.T) {
    var err error
    dsn := "root:@tcp(localhost:3306)/mysql"
    conn, err := sql.Open("mysql", dsn)
    if err != nil {
        panic(err)
    }
    conn.SetMaxOpenConns(10)

    var wg sync.WaitGroup

    for i := 0; i < 10000; i++ {
        wg.Add(1)
        go func() {
            defer func() {
                wg.Done()
                if r := recover(); r != nil {
                    t.Log("[ERROR]", r)
                }
            }()
            rows, err := conn.Query("SELECT host,user FROM user")
            if err != nil {
                panic(err)
            }
            defer rows.Close()
        }()
    }

    wg.Wait()
}
3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!