Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why defer a Rollback?

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?

like image 222
Lars Nielsen Avatar asked Sep 26 '17 08:09

Lars Nielsen


People also ask

Why do we use rollback?

ROLLBACK is a transactional control language in SQL. It lets a user undo those transactions that aren't saved yet in the database. One can make use of this command if they wish to undo any changes or alterations since the execution of the last COMMIT.

What does rollback do in transaction?

You can use ROLLBACK TRANSACTION to erase all data modifications made from the start of the transaction or to a savepoint. It also frees resources held by the transaction. This does not include changes made to local variables or table variables.

What is the importance of commit and rollback in a transaction?

COMMIT permanently saves the changes made by the current transaction. ROLLBACK undo the changes made by the current transaction. 2. The transaction can not undo changes after COMMIT execution.

Can a rollback fail?

If a rollback fails, then you would have a serious problem. The reliability of the database cannot be guaranteed. In other words; you probably have some sort of corruption in your transaction log and will end up with an inconsistent database.


1 Answers

The important thing is that if you defer tx.Rollback() you are sure that it will be called even if you do an early return and the "trick" is that calling tx.Rollback() on a committed transaction will not actually do the rollback, because once a transaction is committed, it's committed and there is no way to roll it back :) So this is a neat trick on how to keep the code simple.

like image 68
Tomor Avatar answered Sep 23 '22 02:09

Tomor