How do I make a scope that is independent of any containing scope *and* does *not* start a new transaction?

135 Views Asked by At

The following code opens a new transaction scope independent of any containing scope:

using (TransactionScope scope = new(TransactionScopeOption.Suppress, asyncFlowOption: TransactionScopeAsyncFlowOption.Enabled))
{
    var connection = _connectionFactory.GetConnection()
    await connection.QueryAsync(...); // e.g. call DB with Dapper 
    await connection.QueryAsync(...); // e.g. another call 
}

(using Dapper)

How do I make a scope that is independent of any containing scope and does not start a new transaction? Essentially, I want the "suppress" option as above, but in a "non-transaction scope".

2

There are 2 best solutions below

0
SNBS On

You can run a thread without passing it a DependentTransaction. It will be independent. Create a function that runs the queries and use this:

using System.Threading.Tasks;

// ...

var task = new Task(FunctionWithQueries);
task.RunSynchronously();
0
Evk On

Transaction.Current is null inside TransactionScope with Suppress option, so connection can't start new transaction because of scope - it has no way to find out scope even exists. If it starts new transaction it must be for another reason.

Note that above I assume you open fresh connection inside suppressed transaction scope, because you use:

var connection = _connectionFactory.GetConnection()

If you do NOT open fresh connection - then Suppress scope essentially does nothing in this case. Ambient transaction is null yes, but your connection already started a transaction before, and so your code inside suppress block will still run inside this same transaction (or it will just fail, for example Entity Framework will notice this situation and throw an exception).