In production all of the sudden we started to have Exception message was "A TransactionScope must be disposed on the same thread that it was created.". Looking into code it was clear we are having .Net Transaction within the async method and TransactionScopeAsyncFlowOption.Enabled is Not used in TransactionScope. What interesting was somehow the above aborted transaction that caused Exception remains attached to the Thread and every API request served by that Thread causes TransactionTimeOut Exception on every db interaction.
I tried to reproduce issue on local by small program. If we see breakpoint we have transaction outside transaction scope. (its not every time , its only for the threads for which exception occurs)
My question is why transaction remains with the thread?
static void Main(string[] args)
{
var loopResult = TxIssue();
while (!loopResult.IsCompleted)
Thread.Sleep(3000);
Console.ReadLine();
}
public static ParallelLoopResult TxIssue()
{
return Parallel.For(0, 10, async t =>
{
try
{
if (Transaction.Current != null)
{
Console.WriteLine($"threadId : {Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"Transaction status = {Transaction.Current.TransactionInformation.LocalIdentifier}");
}
using (var ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
await Task.Delay(300);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
}