golang标准库学习使用Tx事物时遇到的坑
2020-12-21 本文已影响0人
韩小禹
学习使用Tx事物时遇到的坑
- 下面代码就是先删除demo表中的一个记录,然后在demo2中插入一个记录,分别在删除时和插入时对结果做了判断,如果实行失败则tx.Rollback()回滚,成功才tx.Commit()。但是在执行代码时却发现如果在删除时失败,执行tx.Rollback()时没有使用return语句停止程序,则下面的insert语句会保留一个ID(不知道怎么描述比较好),当再次执行执行删除时,如果删除成功,顺序往下执行insert操作时,比较原本id是7,则插入时就变成了8。
下面的代码中的两个return,如果注释掉,就会发现不同。
func tx(){
tx ,err := DB.Begin()
deleteSql := "delete from demo where id = ?"
stmt, err := DB.Prepare(deleteSql)
if err != nil{
log.Fatalf("prepare err ; %v", err)
}
if err != nil{
log.Fatalf("tx err: %v", err)
}
res, err := tx.Stmt(stmt).Exec(17)
if err != nil{
log.Fatalf("tx.stmt.exec err: %v", err)
}
RowsAffected, _ := res.RowsAffected()
if RowsAffected == 0 {
tx.Rollback()
// 如果没有return,则下面的插入操作会比较怪异
return
}
insertSql := "insert into demo2 (name, time) values(?,?)"
stmt, err = DB.Prepare(insertSql)
if err != nil{
log.Fatalf("prepare err: %v", err)
}
res,err = tx.Stmt(stmt).Exec("ethan",time.Now().Format("2006-01-02 15:04:05"))
if err != nil{
log.Fatalf("exec err: %v",err)
}
lastIndexId,_:= res.LastInsertId()
if lastIndexId == 0{
tx.Rollback()
return
}
tx.Commit()
}