-
Notifications
You must be signed in to change notification settings - Fork 0
Description
From VividCortex/go-database-sql-tutorial#85 (review):
Every transaction must end with either a
Commit
orRollback
. Deferring theRollback
is a safeguard to make sure it's called no matter what. The alternative is that youRollback
in every single error return. Miss one and you'll leak the transaction. Even if you diligently add it to all returns, you still have the problem of a potential panic that your application recovers later on. Deferring allows you to handle all this.The problem of "always" running a rollback is not really an issue. It may seem counterintuitive at first, but
database/sql
actually guarantees that once the transaction is first closed (either byCommit
orRollback
), subsequent attempts at closing it will be gracefully ignored. From the docs:After a call to Commit or Rollback, all operations on the transaction fail with ErrTxDone.
This means that the only thing you need to worry about is the
Commit
when you're ready to do so. Any other path will automatically get aRollback
and, if you actually reached theCommit
, the deferredRollback
will be a harmless no-op.As for the
Error
versusFatal
... you're right, a typical application won't simply exit. Examples are typically a bit vague on error handling to avoid introducing complexity that's not really the point and may become a distraction. In this case the change toError
is not always correct either. If you failed todb.Begin
a transaction, then you can't proceed and try totx.Prepare
. (I mean... you can, but it's not a good practice. It will also fail at best, or maybe even crash your application.) Likewise, if you couldn't prepare thestmt
, then trying toExec
it is not going to work. Usinglog.Fatal
is a simplification in terms of error handling, assuming that people can fill in the appropriate handling. We could put areturn
clause here instead if it helps. We need to show that this flow can't/shouldn't be continued, whether by returning or aborting the application. Changing tolog.Error
is actually doing a disfavor in my opinion.