There’s a huge whopping gaping hole of a bug in .NET 2.0 (and also by default in .NET 3.5) with the interaction between the native SqlClient and the System.Transactions code when lightweight transactions are in use.
Basically, it goes like this
- You start a transaction with a time out
- You do some work on your transacted connection
- The timeout triggers in the background, and
- The transaction gets rolled back
- The connection is left in the default "auto commit" mode
- NO EXCEPTION GETS RAISED
- You do some more work on what you think is your transacted connection and NO EXCEPTION GETS RAISED
- You go to commit or rollback and it raises an exception which says "What transaction? I already rolled it back!"
Now, go look in the database, and Shock! Horror! All the stuff you did in Step 2 has been rolled back, but all the stuff you did in step 4 is there! Half a transaction! Argh!