Why is a nested transaction committed even if TransactionScope.Complete() is never called?

前端 未结 2 833
面向向阳花
面向向阳花 2021-01-15 23:05

I was testing to see how nested transactions work, and uncovered this disturbing and unexpected behavior.

using(TransactionScope otx = new TransactionScope()         


        
相关标签:
2条回答
  • 2021-01-15 23:12

    Your second Command object is being created on conn1, not conn2, so it's very much like the other question - the connection on which you're running the command was opened before the second transaction scope was opened.

    0 讨论(0)
  • 2021-01-15 23:28

    First off, there is no such thing as a nested transaction in SQL Server. This is important.

    Second, both TransactionScopes use conn1 so you are (at the SQL Server level) incrementing @@TRANCOUNT for each BEGIN TRANSACTION

    Simple explanation: the inner transaction is committed when the outer transaction commits because rolling back the inner would rollback both transactions

    That is, COMMIT TRANSACTION (implied by .Complete and .Dispose) decrements @@TRANCOUNT while ROLLBACK TRANSACTION (implied by .Dispose only) takes it back to zero. So the inner rollback is suppressed because of "no such thing as nested transactions"

    If you'd used conn2 correctly in the inner 'scope it would work as expected because the 2 transactions are unrelated at the database server level. Which is where it matters...

    0 讨论(0)
提交回复
热议问题