Will an inner transaction scope roll back if the outer transaction scope doesn't complete?

C#Transactionscope

C# Problem Overview


I have two transaction scopes, one within another. I would love to know if the inner transaction scope will be rolled back after it has been committed and the outer one does not complete.

C# Solutions


Solution 1 - C#

It depends on the scope option you start the nested transaction scope with.

If you use the default option TransactionScopeOption.Required then the nested scope will enlist in the same transaction as the outer scope and as such when the outer scope rolls back the inner scope will also be rolled back even if it has called Complete.

If, however, you use TransactionScopeOption.RequiresNew then the nested scope will begin its own transaction and complete it separately from the outer scope, so it will not roll back even if the outer scope rolls back.

If you use TransactionScopeOption.Suppress then the nested scope will not take part in the outer transaction and will complete non-transactionally, thus does not form part of the work that would be rolled back if the outer transaction rolls back.

Solution 2 - C#

Since they are nested, the inner transaction will roll back.

This is not the whole story, and depends on how you create the nested transaction, but by default, it will roll back.

This article goes into depth about TransactionScope and should answer most of your questions.


Being distributed or not is irrelevant.

Solution 3 - C#

Yes it will, you can refer to code below. Following code wil roll back outer transaction scope if inner transaction throw error and vice versa.

   public bool rootMethod(){
          using (var transaction = new(TransactionScopeOption.RequiresNew))
           try{
           // your code here
           SomeController someController = new SomeController();
           var responseFromChildMethod = someController.childMethodWithTxn();

       // your logic here

       transaction.Complete();
       return true;
       }
       catch(Exception ex){
       transaction.Dispose();
       return false;
       }
    } 
}

SomeController.cs

public bool childMethodWithTxn(){
  using(var newTransaction =  new TransactionScope()){
    try{
      //your code here
      newTransaction.Complete();
      return true;
    }
    catch(Exception ex){
           newTransaction.Dispose();
           return false;
           }

  }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOrsonView Question on Stackoverflow
Solution 1 - C#Greg BeechView Answer on Stackoverflow
Solution 2 - C#OdedView Answer on Stackoverflow
Solution 3 - C#Gaurav BasnetView Answer on Stackoverflow