2017-09-26 85 views
0

我一直在使用去一个web服务起步,并没有一些数据库交互(惊喜!),我发现这个例子:为什么推迟回滚?

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! 

http://go-database-sql.org/prepared.html

的例子很好地制定了一个简单的了解。但是,这给我留下了一个没有答案的问题。为什么defer事务回滚调用?

为什么不只是做到以下几点:

err := tx.Commit() 

if err != nil { 
    log.Error(err) 
    tx.Rollback() 
} 

defer tx.Rollback()并不总是试图回滚?即使tx.Commit()是成功的,或者我误解了defer的一些内容?

+0

看起来像一个错误。正如你所说,除非发生错误,否则你不想回滚。另外log.Fatalf你不想在一个真正的应用程序。我建议使用改进此页面按钮并联系作者。 –

+0

谢谢你的回答:) –

回答

1

这个例子有点让人误解。它使用log.Fatal(err)进行错误处理。你通常不会这样做,而是return err。所以延迟回滚就是为了确保事务在提前返回的情况下回滚。

+0

是的,我知道log.Fatal部分:)非常感谢你的回答 –