2011-10-31 50 views
7

Chúng tôi đang cố gắng để thực hiện giao dịch làm tổ gián tiếp bằng cách sử dụng mã dưới đây, .NET 3.5, & SQL Server 2005.sử dụng TransactionScope: System.Transactions.TransactionAbortedException: Giao dịch đã bị hủy bỏ

MSDN nói rằng khi sử dụng TransactionScope, một giao dịch được leo thang bất cứ khi nào ứng dụng mở một kết nối thứ hai (thậm chí đến cùng cơ sở dữ liệu) trong Giao dịch.

void RootMethod() 
{ 
    using(TransactionScope scope = new TransactionScope()) 
    { 
     /* Perform transactional work here */ 
     FirstMethod(); 
     SecondMethod(); 
     scope.Complete(); 
    } 
} 

void FirstMethod() 
{ 
    using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) 
    { 
    using (SqlConnection conn1 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI")) 
     { 
    string insertString = @" 
      insert into Categories 
      (CategoryName, Description) 
      values ('Laptop1', 'Model001')"; 
     conn1.Open(); 
     SqlCommand cmd = new SqlCommand(insertString, conn1); 
     cmd.ExecuteNonQuery(); 
     } 
     scope.Complete(); 
    } 
} 

void SecondMethod() 
{ 
    using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) 
    { 
     using (SqlConnection conn2 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI")) 
     { 
    string insertString = @" 
      insert into Categories 
      (CategoryName, Description) 
      values ('Laptop2', 'Model002')"; 

     conn2.Open(); //Looks like transactionabortedException is happening here 
     SqlCommand cmd = new SqlCommand(insertString, conn2); 
     cmd.ExecuteNonQuery(); 
     } 
     scope.Complete(); 
    } 
    } 

Thỉnh thoảng, những giao dịch thất bại đó, không được thúc đẩy để DTC, và chúng tôi đang nhận được sau khi vết đống bên trong,

System.Transactions.TransactionAbortedException: The transaction has aborted. ---> 
System.Transactions.TransactionPromotionException: Failure while attempting to promote transaction. ---> 
System.InvalidOperationException: The requested operation cannot be completed because the connection has been broken.  
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)  
at System.Data.SqlClient.SqlDelegatedTransaction.Promote()  --- End of inner exception stack trace ---  
at System.Data.SqlClient.SqlDelegatedTransaction.Promote()  
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)  
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)  
--- End of inner exception stack trace ---  
at System.Transactions.TransactionStateAborted.CreateAbortingClone(InternalTransaction tx)  
at System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking)  
at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)  
at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent)  
at System.Transactions.TransactionScope.PushScope()  
at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption)  

bất cứ ai có thể vui lòng giúp tôi tìm ra lý do cho điều này thất bại?

+0

Bạn đã thử đóng kết nối chưa? Đôi khi tôi nhận được lỗi như vậy, khi kết nối đã được mở. Có thể tôi có thể sai. –

+0

bạn đã thử thêm *; MultipleActiveResultSets = True * trong chuỗi kết nối –

Trả lời

0

tôi có thể đề xuất với bạn một cách tốt hơn để đạt được mục tiêu của bạn. sẽ có một giao dịch duy nhất cho 2 cuộc gọi DB cho mỗi kết nối.

nó nên được như thế

using (SqlConnection conn1 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI")) 
{ 
    using (conn1.BeginTransaction() 
    { 
     try 
     { 
      FirstMethod(Conn1); 
      SecondMethod(Conn2); 
     } 
     catch() 
     { 
     } 
    } 
} 
+3

Bạn không thể nói đây là giải pháp tốt hơn. Nếu bạn không thể thay đổi phương thức để chấp nhận kết nối thì sao? Điều gì sẽ xảy ra nếu các phương thức trong các đối tượng khác nhau? Điều gì sẽ xảy ra nếu các phương pháp đó đã có quá nhiều tham số? Và điều này là xấu xí quá. –

3

Nếu bạn sử dụng TransactionScope và bạn:

  • mở nhiều hơn một kết nối đến một cơ sở dữ liệu và
  • được kết nối với một SQL Server 2005 máy chủ

giao dịch sẽ được chuyển đến DTC. Kiểm tra này khác SO câu hỏi: TransactionScope automatically escalating to MSDTC on some machines?

Giải pháp là một trong hai:

  • Sử dụng SQL Server 2008 hoặc
  • Sử dụng SqlTransaction thay vì TransactionScope giống như câu trả lời cựu gợi ý:

    using (var conn = new SqlConnection(connectionString)) 
    { 
        using (var tx = conn.BeginTransaction()) 
        { 
         FirstMethod(conn); 
         SecondMethod(conn); 
         tx.Commit(); 
        } 
    } 
    
Các vấn đề liên quan