2012-08-27 14 views
5

में वृद्धि के बिना एसक्यूएलसीएलआर में ट्रांज़ेक्शनस्कोप का उपयोग कैसे करें हमारे बहुत सारे डीएएल कोड लेनदेन के लिए ट्रांज़ेक्शनस्कोप का उपयोग करते हैं। यह बहुत अच्छा काम करता है लेकिन एक समस्या है जब मैं इस डीएएल कोड का उपयोग SQLCLR प्रक्रिया के अंदर से करता हूं। लेनदेन एमएसडीटीसी को बढ़ाया गया है जो मैं नहीं चाहता हूं।एमएसडीटीसी

समस्या आसानी से reproduced किया जा सकता है:

  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 स्क्रिप्ट CLR प्रक्रिया

    BEGIN TRANSACTION 
    
    exec dbo.ClrWithTrans "select * from sys.tables"; 
    exec dbo.ClrWithScope "select * from sys.tables"; /* <- DOES NOT WORK! */ 
    
    ROLLBACK TRANSACTION 
    
  3. निष्पादित करने के लिए इस्तेमाल किया

    त्रुटि

    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. 
    

"BEGIN लेन-देन" बयान wihtout, dbo.ClrWithScope कॉल ठीक काम करता है। मुझे लगता है कि .NET Framework में सूचीबद्ध करते समय SQLServer द्वारा शुरू किया गया लेनदेन नहीं माना जाता है।

क्या इसके आसपास आने का कोई समाधान है। एक विचार है कि मैन्युअल रूप से एसक्यूएलट्रांसक्शन बनाएं और लेनदेन का उपयोग इस लेनदेन का उपयोग करने के लिए करें, लेकिन मुझे नहीं पता कि यह कैसे करें। एक और समाधान सभी डीएएल कोड में एक विशेष मामला बनाना होगा (लागू करने के लिए वास्तव में मजाकिया नहीं)।

कोई विचार?

+0

'Scope' – Magnus

+0

@Magnus के आसपास' Connection' डालने की कोशिश लेकिन वह नहीं (स्वतः) परिवेश के लेनदेन में कनेक्शन है, जो TransactionScope का पूरा उद्देश्य है, है ना भर्ती करता है? –

+0

ईसाई.के सही है। डीएएल कोड लेनदेनस्कोप और एसक्यूएलकनेक्शन का बहुत उपयोग कर रहा है। बेशक डीएएल में पूरे कोडबेस को फिर से लिखना संभव है लेकिन यह अच्छा नहीं है। – sschoenb

उत्तर

1

एसक्यूएल सीएलआर के भीतर लेनदेनस्कोप का उपयोग हमेशा एमएसडीटीसी लेनदेन को बढ़ावा/बढ़ाएगा। वहाँ 2012

TechNet से SQL CLR और TransactionScope (http://technet.microsoft.com/en-us/library/ms131084.aspx)

के बारे में भी एसक्यूएल में, इस के आसपास किसी भी तरह से होना प्रतीत नहीं होता है

TransactionScope केवल जब स्थानीय और दूरस्थ डेटा स्रोतों या बाहरी इस्तेमाल किया जाना चाहिए संसाधन प्रबंधकों का उपयोग किया जा रहा है। यह है क्योंकि लेनदेन स्कोप हमेशा लेनदेन का कारण बनता है, यहां तक ​​कि यदि इसका उपयोग केवल संदर्भ कनेक्शन में किया जा रहा है।