Looking into the documentation it says that the Rollback method can throw when the transaction is not in pending state (after begin transaction and before commit transaction).
I can’t seem to find a way to check whether the transaction can be rollback or not. There isn’t a state property either.
Ideally, just wrap your transaction with a “using” statement or use a TransactionScope object, which will automatically rollback if an exception is thrown or if the transaction is not commited before it goes out of scope.
The rest of the time, as ugly as it is, I usually wrap my rollbacks in an empty try/catch block, because it is almost always in a catch handler that has a more meaningful exception. The idea is that we only want to rollback if we can, but we don’t want to start throwing new exceptions if we can’t (for any number unpredictable reasons), because the transaction will get rolled back as long as it’s not committed anyway. You still need to try to clean up properly so it doesn’t need to wait for the garbage collector, but if you can’t, then the rollback isn’t the real problem.
Note: don’t explicity re-throw the exception (i.e. “throw theExceptionICareAbout”), because that will recreate the stack trace. Instead, just use “throw” which will continue the existing exception stack.