事务就是 保证不同的sql 语句同时成功,或者同时失败的方法。基础用法就不说了,我发现很多人在执行事务 commit , rollback的时候 并不判断是否成功或者失败,也不记录日志。这个虽然说有一点点难度,但是还是非常好做的,可能大家都受到官网文档误导了。
官网文档用的时候就不判断错误,不判断错误如果rollback出错了,没日志,定位会很难,数据不一致问题也非常严重,真是误人子弟!
```
package main
import (
"database/sql"
"x/log.v7"
)
func logRollback(tx *sql.Tx) {
err := tx.Rollback()
if err != tx.ErrTxDone && err != nil {
log.Error()
}
}
func main() {
tx, err := sql.DB.Begin()
if err != nil {
log.Error()
return
}
defer logRollback(tx) // 此处必须用defer, defer 很多人理解为怕忘记了,先写上,其实defer真正的作用是无论如何都能执行到,即使 panic,当然如果在 defer 函数前就panic得情况下,也是没办法执行的。我当初也理解错defer了。也是因为这个原因我想很多人就不记录日志了吧。其实也能用defer func,都可以,记录错误就可以
if result, err := tx.Exec(query1); err != nil {
log.Error()
return
}
doSomething()
if row, err := tx.Query(query2); err != nil {
log.Error() // 此处调用 rollback 是不对的, 因为在 doSomething 可能panic,这样 rollback就执行不到了,所以上面必须用defer
return
}
if err := tx.Commit(); err != nil {
log.Error()
return
}
}
```
有疑问加站长微信联系(非本文作者)