Search code examples
.netdatabasetransactionstransactionscope

Is it possible to step outside of the current TransactionScope and insert data


Consider the following:

using (var outerScope = new TransactionScope())
{
    InsertDataInTableOne();
    InsertDataInTableTwo();
    InsertDataInTableThree();
    outerScope.Complete();
}

Now I want to have InsertDataInTableOne to be run outside of the outerScope transaction. This is a simplified representation, as the TransactionScope is created several calls up the chain, so I can't just put the call to InsertDataInTableOne outside of the TransactionScope creation.

I also know this might not be a good practice, and we're working on a decent fix. But we need this quick fix at this moment.

using (var outerScope = new TransactionScope())
{
    using (var innerScope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        InsertDataInTableOne();
        innerScope.Complete();
    }
    InsertDataInTableTwo();
    InsertDataInTableThree();
    outerScope.Complete();
}

That didn't work. I even tried with creating a TransactionScope with Suppress first, and then the RequiresNew.

So is it possible to insert data immediately in the database, effectively ignoring the fact that you are in a TransactionScope?

The connection is made outside of these methods (actually, when entering the service that is called).


Solution

  • Not sure if this will help anyone, but you never know. The problem lies with a custom company-framework. The implementation makes it hard to have nested transactions, I believe. We fixed it now by removing the outer transaction (which is several layers up) and creating two separate transactions in our block:

    using (var scopeOne = new TransactionScope())
    {
        InsertDataInTableOne();
        scopeOne.Complete();
    }
    
    using (var scopeTwo = new TransactionScope())
    {
        InsertDataInTableTwo();
        InsertDataInTableThree();
        scopeTwo.Complete();
    }
    

    Again, this is a solution very specific to our code. Using RequiresNew should normally do the trick. So if it doesn't work, maybe look into your own code first ;)

    Another reason why I'm not a huge fan of do-it-all-company-frameworks.