2012-08-27 3 views
5

多くのDALコードでは、トランザクションにTransactionScopeが使用されています。それは素晴らしいですが、SQLCLRプロシージャの内部からこのDALコードを使用すると問題が発生します。トランザクションは私が望まないものをMSDTCにエスカレートされます。 CLR手順MSDTCへのエスカレーションなしでSQLCLRでTransactionScopeを使用する方法

BEGIN TRANSACTION 

exec dbo.ClrWithTrans "select * from sys.tables"; 
exec dbo.ClrWithScope "select * from sys.tables"; /* <- DOES NOT WORK! */ 

ROLLBACK TRANSACTION 
  • を実行するために使用

    1. CLR実装

      [SqlProcedure] 
      public static void ClrWithScope(string cmdText) 
      { 
          /* escalates to MSDTC when a transaction is already open */ 
          using (var scope = new TransactionScope()) 
          { 
           using (var connection = new SqlConnection("context connection=true;")) 
           { 
            connection.Open(); 
            using (var cmd = new SqlCommand(cmdText, connection)) 
            { 
             SqlContext.Pipe.ExecuteAndSend(cmd); 
            } 
           } 
           scope.Complete(); 
          } 
      } 
      
      [SqlProcedure] 
      public static void ClrWithTrans(string cmdText) 
      { 
          /* works as expected (without MSDTC escalation) */ 
          using (var connection = new SqlConnection("context connection=true;")) 
          { 
           connection.Open(); 
           using (var tx = connection.BeginTransaction()) 
           { 
            using (var cmd = new SqlCommand(cmdText, connection, tx)) 
            { 
             SqlContext.Pipe.ExecuteAndSend(cmd); 
             tx.Commit(); 
            } 
           } 
          } 
      } 
      

    2. SQLスクリプト:

      問題を簡単に再現できます"TRANSACTIONをBEGIN" 文WIHTOUT

      エラー

      Msg 6549, Level 16, State 1, Procedure ClrWithScope, Line 0 
      A .NET Framework error occurred during execution of user defined routine or aggregate 'clrClrWithScope': 
      System.Transactions.TransactionAbortedException: Die Transaktion wurde abgebrochen. ---> System.Transactions.TransactionPromotionException: MSDTC on server 'BLABLA' is unavailable. ---> System.Data.SqlClient.SqlException: MSDTC on server 'BLABLA' is unavailable. 
      System.Data.SqlClient.SqlException: 
          bei System.Data.SqlServer.Internal.StandardEventSink.HandleErrors() 
          bei System.Data.SqlServer.Internal.ClrLevelContext.SuperiorTransaction.Promote() 
      System.Transactions.TransactionPromotionException: 
          bei System.Data.SqlServer.Internal.ClrLevelContext.SuperiorTransaction.Promote() 
          bei System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx) 
          bei System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx) 
      System.Transactions.TransactionAbortedException: 
          bei System.Transactions.TransactionStateAborted.CreateAbortingClone(InternalTransaction tx) 
          bei System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking) 
          bei System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption) 
          bei System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent) 
          bei System.Transactions.TransactionScope.PushScope() 
          bei System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption) 
          bei Giag.Silo.Data.SqlClr.ClrWithScope(String cmdText) 
      . User transaction, if any, will be rolled back. 
      

    、dbo.ClrWithScopeコールがOKに動作します。私は、SQLServerによって開始されたトランザクションは.Net Frameworkに参加している間は考慮されないと考えています。

    これを解決する方法はありますか。手動でSqlTransactionを作成し、このトランザクションを使用するようにTransactionScopeを作成することが考えられますが、これを行う方法はわかりません。もう1つの解決策は、DALコードのすべてで特殊なケースを作ることです(実装するのは面白くない)。

    アイデア?

  • +0

    は 'Scope' – Magnus

    +0

    @Magnus周り' Connection'を入れてみてくださいしかし、それは(自動的に)のTransactionScopeの全体の目的で周囲のトランザクションへの接続を参加しない、それはないですか? –

    +0

    Christian.Kが正しいです。 DALコードは、TransactionScopeとSqlConnectionを多く使用しています。もちろん、DALでコードベース全体を書き換えることは可能ですが、それはうまくありません。 – sschoenb

    答えて

    1

    SQL内でTransactionScopeを使用するCLRは常にMSDTCトランザクションを昇格/エスカレートします。 SQLのCLRとのTransactionScope(http://technet.microsoft.com/en-us/library/ms131084.aspx

    に関する2012年のTechNetから

    でもSQLで、この周りにどのような方法があるように表示されません

    TransactionScopeのは、ときにのみ、ローカルおよびリモートのデータ ソースまたは外部で使用する必要がありますリソースマネージャにアクセスしています。これは です.ContentScopeはトランザクションの昇格を常に発生させるため、コンテキスト接続内でのみ使用されている場合は となります。

    関連する問題