微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

事务中的golang sql / database预处理语句

如何解决事务中的golang sql / database预处理语句

一个defer说法是一个很好的方式,以确保运行的东西不管你怎么退出功能

在这种特殊情况下,这似乎无关紧要,因为所有错误处理程序都使用log.Fatal。如果log.Fatalreturn语句替换s 并删除延迟,则现在必须在许多地方进行清理:

tx, err := db.Begin()
if err != nil {
    return nil,err
}
stmt, err := tx.Prepare("INSERT INTO foo VALUES (?)")
if err != nil {
    tx.Rollback()
    return nil,err
}
defer 
for i := 0; i < 10; i++ {
    _, err = stmt.Exec(i)
    if err != nil {
        tx.Rollback()
        return nil,err
    }
}
err = tx.Commit()
if err != nil {
    stmt.Close()
    tx.Rollback()
    return nil,err
}
stmt.Close()
return someValue, nil

如果使用延迟,则很难忘记需要清理的地方。

解决方法

在阅读golang SQL /数据库示例中“事务”中“准备”语句的示例时。其中一行说“危险”,但提供的代码示例没有其他选择。

我想对下面的查询有更清晰的解释,因为Wiki页面-http://go-database-sql.org/prepared.html上没有提供太多信息。

tx,err := db.Begin()
if err != nil {
    log.Fatal(err)
}
defer tx.Rollback()
stmt,err := tx.Prepare("INSERT INTO foo VALUES (?)")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close() // danger!
for i := 0; i < 10; i++ {
    _,err = stmt.Exec(i)
    if err != nil {
        log.Fatal(err)
    }
}
err = tx.Commit()
if err != nil {
    log.Fatal(err)
}
// stmt.Close() runs here!

如果您在defer stmt.Close()其中看到提及内容,那是很危险的,但还没有注释掉,请用户删除。

尽管我在上面的代码中没有看到问题,因为“ defer”将在最后运行代码,但这是否意味着,上面的代码是错误的,应将其替换为下面的代码或其他更好的替代代码。

tx,err := tx.Prepare("INSERT INTO foo VALUES (?)")
if err != nil {
    log.Fatal(err)
}
// Commented out below line.
// defer stmt.Close()
for i := 0; i < 10; i++ {
    _,err = stmt.Exec(i)
    if err != nil {
        log.Fatal(err)
    }
}
err = tx.Commit()
if err != nil {
    log.Fatal(err)
}
// Comment removed from below line to close the stmt
stmt.Close()

我发现上面的两个代码没有什么区别,但是,如果有任何区别或缺少某些内容,我需要上面的专家建议。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。