如何解决事务中的golang sql / database预处理语句
一个defer
说法是一个很好的方式,以确保运行的东西不管你怎么退出功能。
在这种特殊情况下,这似乎无关紧要,因为所有错误处理程序都使用log.Fatal
。如果log.Fatal
用return
语句替换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 举报,一经查实,本站将立刻删除。