簡體   English   中英

如何在SQLCLR中使用TransactionScope而不升級到MSDTC

[英]How to use TransactionScope in SQLCLR without escalation to MSDTC

我們的許多DAL代碼都使用TransactionScope進行交易。 這很好用,但是當我在SQLCLR程序中使用這個DAL代碼時會出現問題。 交易升級到MSDTC我不想要的。

問題可以輕松復制:

  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. 用於執行CLR過程的SQL腳本

     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. 

WIHTOUT“BEGIN TRANSACTION”語句,dbo.ClrWithScope調用工作正常。 我想在登錄.Net Framework時不考慮SQLServer啟動的事務。

是否有解決方案來解決這個問題。 一個想法是手動創建一個SqlTransaction並使TransactionScope使用此事務,但我不知道如何做到這一點。 另一種解決方案是在所有DAL代碼中創建一個特殊情況(實現起來並不是很有趣)。

有任何想法嗎 ?

在SQL CLR中使用TransactionScope將始終提升/升級到MSDTC事務。 即使在SQL 2012中,似乎也沒有任何解決方法。

從TechNet關於SQL CLR和TransactionScope( http://technet.microsoft.com/en-us/library/ms131084.aspx

只有在訪問本地和遠程數據源或外部資源管理器時,才應使用TransactionScope。 這是因為TransactionScope總是會導致事務被提升,即使它僅在上下文連接中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM