I do not confess to being a database expert, nor a guru in T-SQL, which is why I have only just found out how crap transactions in T-SQL on SQL Server 2000 can be. Take a look at the following piece of T-SQL:
The above script creates two temporary tables, attempts to insert a value in the first, and then a NULL in the second table. Since #Foo2.PK does not allow NULL values, the second insert fails. I naively assumed that because I have wrapped the insert statements in a transaction, the commit will only complete if no error occurs. This is not the case. The commit statement commits the first insert but not the second - not exactly what I had in mind.
The problem experienced above, is partially due to bad coding on my part because I did not initially understand the intricacies of how SQL Server 2000 manages transactions - the user is responsible for managing the roll back of a transaction after a statement error. The correct approach would have been to check the @@ERROR value for non-zero after each statement in the transaction block to see if a roll back was required. This can be a real chore if a transaction has many statements, and especially annoying if the error number of any one statement be reported, and the transaction aborted upon an error (typical behavior). Fortunately, SQL Server 2005 comes to the rescue with try-catch - similar to that of how ADO.NET deals with transactions. The following code will produce the desired results in SQL Server 2005: