В чем разница между TransactionScopeAsyncFlowOption.Enabled
и TransactionScopeOption.RequiresNew
+ зависимыми транзакциями?
Я пытаюсь выполнить 3 async
задач в 3 отдельных потоках, пока все они находятся в транзакции. Невозможно использовать IDbTransaction
, поскольку задачи выполняют операции с несколькими базами данных. Я создал 2 примера возможных реализаций:
Использование TransactionScopeAsyncFlowOption.Enabled
:
try
{
using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
List<System.Threading.Tasks.Task> tasks = new List<System.Threading.Tasks.Task>();
System.Threading.Tasks.Task t1 = new System.Threading.Tasks.Task(() => DoSomething1());
t1.Start();
tasks.Add(t1);
System.Threading.Tasks.Task t2 = new System.Threading.Tasks.Task(() => DoSomething2());
t2.Start();
tasks.Add(t2);
System.Threading.Tasks.Task t3 = new System.Threading.Tasks.Task(() => DoSomething3());
t3.Start();
tasks.Add(t3);
System.Threading.Tasks.Task.WaitAll(tasks.ToArray());
scope.Complete();
}
}
catch (Exception ex)
{
return ex.Message;
}
Использование зависимых транзакций:
try
{
using (TransactionScope trans = new TransactionScope(TransactionScopeOption.RequiresNew))
{
Thread t1 = new Thread(p =>
{
DependentTransaction dTrans = (DependentTransaction)p;
try
{
using (TransactionScope childTrans = new TransactionScope(dTrans))
{
DoSomething1();
childTrans.Complete();
}
dTrans.Complete();
}
catch (Exception ex)
{
dTrans.Rollback(ex);
}
});
Thread t2 = new Thread(delegate(Object p)
{
DependentTransaction dTrans = (DependentTransaction)p;
try
{
using (TransactionScope childTrans = new TransactionScope(dTrans))
{
DoSomething2();
childTrans.Complete();
}
dTrans.Complete();
}
catch (Exception ex)
{
dTrans.Rollback(ex);
}
});
Thread t3 = new Thread(delegate(Object p)
{
DependentTransaction dTrans = (DependentTransaction) p;
try
{
using (TransactionScope childTrans = new TransactionScope(dTrans))
{
DoSomething3();
childTrans.Complete();
}
dTrans.Complete();
}
catch (Exception ex)
{
dTrans.Rollback(ex);
}
});
t1.Start(Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete));
t2.Start(Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete));
t3.Start(Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete));
t1.Join();
t2.Join();
t3.Join();
trans.Complete();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Я пытался найти больше информации в Интернете, но все еще не могу понять, какой из подходов лучше и в чем различия?