当在golang中而不是在查询段中但在“ rows.Next()”循环之外查询mysql时发生死锁错误

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

[当我使用golang查询mysql时,有时我在代码中发现“ deadlock err”。

我的问题不是“为什么发生死锁”,而是为什么在“ err = rows.Err()”中发现死锁err。在我看来,如果发生死锁,我应该在“ tx.Query”的返回错误中得到它。

这是演示代码,“点2”是发生死锁错误的位置


func demoFunc(tx *sql.Tx, arg1, arg2 int) ([]outItem, error) {
    var ret []outItem
    var err error
    var rows *sql.Rows

    //xxxLockSql may deadlock, so try again for 3-times
    for i := 0; i < 3; i++ {
        //------ point 1
        rows, err = tx.Query(xxxLockSql, arg1, arg2)
        if err == nil {
            break
        }

        log.Printf("[ERROR] xxxLockSql failed, err %s, retry %d", err.Error(), i)
        time.Sleep(time.Millisecond * 10)
    }

    //if query xxxLockSql failed up to 3-times, then return
    if err != nil {
        log.Printf("[ERROR] xxxLockSql failed, err %s", err.Error())
        return ret, err
    }

    defer rows.Close()

    for rows.Next() {
        err = rows.Scan(&a1, &a2)
        if err != nil {
            return ret, err
        }

        ret = append(ret, acl)
    }

    //------ point 2
    if err = rows.Err(); err != nil {
        // i found deadlock err in this "if" segment.
        // err content is "Error 1213: Deadlock found when trying to get lock; try restarting transaction" 
        log.Printf("[ERROR] loop rows failed, err %s", err.Error())
        return ret, err
    }

    return ret, nil
}
mysql go deadlock
1个回答
0
投票

我不确定原因,因为您没有提到数据库驱动程序(以及您使用的是哪个sql软件包)。但是我认为这是因为sql.Query是惰性的,这意味着查询和加载行被推迟到实际使用为止,即rows.Next()-这就是在那里发生死锁错误的原因。

由于它为什么不在循环中,是因为当发生错误时,rows.Next()返回false并中断了循环。

© www.soinside.com 2019 - 2024. All rights reserved.