为什么要推迟回滚?

为什么要推迟回滚?

问题描述:

I have started using Go for a web-service and have some database interaction (surprise!!!) and I have found this example:

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!

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

The example is well formulated an easy to understand. However, it leaves me with an unanswered question. Why defer the transaction Rollback call?

Why not just do the following:

err := tx.Commit()

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

Would defer tx.Rollback() not always attempt a rollback? Even if tx.Commit() was a success, or have I misunderstood something about defer?

The example is a little bit misleading. It uses log.Fatal(err) for error handling. You wouldn't normally do that, and instead return err. So the deferred rollback is there to ensure that the transaction is rolled back in case of an early return.