4

次の小さなプログラムを考えてみましょう。単純にTransactionScope, 印刷を作成し、Transaction.Current別の AppDomain のメソッドを呼び出し (実行に時間がかかります)、戻ったときに印刷Transaction.Currentします。

using System;

using System.Linq;
using System.Runtime.Remoting.Lifetime;
using System.Threading;
using System.Transactions;

namespace TransactionScopeFlowTest
{
   class Program
   {
      static void Main(string[] args)
      {
         // These times are just to generate the error faster. Normally the initial lease is 5 minutes, meaning the method call
         // would have to take 5 minutes to occur, so we speed it up here for demonstration purposes.
         LifetimeServices.LeaseManagerPollTime = TimeSpan.FromSeconds(1);
         LifetimeServices.LeaseTime = TimeSpan.FromSeconds(1);
         LifetimeServices.RenewOnCallTime = TimeSpan.FromSeconds(1);

         AppDomain domain = AppDomain.CreateDomain("Temp", null, AppDomain.CurrentDomain.SetupInformation);

         using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
         {
            Console.WriteLine($"Transaction Before Call = {Transaction.Current?.TransactionInformation?.LocalIdentifier?.ToString() ?? "<null>"}");
            domain.DoCallBack(AppDomainCallback);
            Console.WriteLine($"Transaction After Call = {Transaction.Current?.TransactionInformation?.LocalIdentifier?.ToString() ?? "<null>"}");
            scope.Complete();
         }

         AppDomain.Unload(domain);
      }

      public static void AppDomainCallback()
      {
         Thread.Sleep(3000);
      }
   }
}

まったく予想外に、プログラムは次の出力を生成します。

Transaction Before Call = 1f980219-2583-4796-8d6d-256a6f100698:1
Transaction After Call = <null>

TransactionScopeAsyncFlowOptionの ctor をTransactionScopeに変更するとTransactionScopeAsyncFlowOption.Suppress、トランザクションは呼び出し後に残ります。

私の疑いでは、論理コンテキスト全体のトランザクション スコープ フローは、リモーティング呼び出し全体に伝播される CallContext によって処理され、使用されるキーは継承MarshalByRefObjectされ、どのキーにも登録されていないためISponsor、プロキシは最初のリース時間の後に切断されます。そして、呼び出しから戻ると、論理呼び出しコンテキストが元のコンテキストにマージされます。つまり、トランザクションは存在しなくなります。

この問題を回避する方法を探しています。また、これが .NET のバグと見なされる場合は?

4

0 に答える 0