TransactionScope в нескольких потоках с операциями между базами данных - PullRequest
0 голосов
/ 25 июня 2018

В чем разница между 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());
}

Я пытался найти больше информации в Интернете, но все еще не могу понять, какой из подходов лучше и в чем различия?

...