2012-07-12 30 views
46

Tôi đã gặp sự cố khi sử dụng TransactionScope để bao gồm nhiều truy vấn cơ sở dữ liệu vào giao dịch, tôi đang sử dụng SqlBulkCopy với batchsize 500. Khi tôi tăng lô kích thước đến 1000 tôi nhận được lỗi:Lỗi - Giao dịch liên kết với kết nối hiện tại đã hoàn thành nhưng chưa được xử lý

The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements.

Đây là mã tôi đang sử dụng:

using (var scope = new TransactionScope()) 
{ 
    using (var connection = (SqlConnection)customerTable.OpenConnection()) 
    { 
     var table1BulkCopy = new SqlBulkCopy(connection) 
     { 
      BatchSize = BATCH_SIZE, 
      DestinationTableName = TableName1 
     }; 

     table1BulkCopy.WriteToServer(table1DataTable); 

     var table2BulkCopy = new SqlBulkCopy(connection) 
     { 
      BatchSize = BATCH_SIZE, 
      DestinationTableName = TableName2 
     }; 

     table2BulkCopy.WriteToServer(table2DataTable); 

     var table3BulkCopy = new SqlBulkCopy(connection) 
     { 
      BatchSize = BATCH_SIZE, 
      DestinationTableName = TableName3 
     }; 

     table1BulkCopy.WriteToServer(table3DataTable); 

     var table4BulkCopy = new SqlBulkCopy(connection) 
     { 
      BatchSize = BATCH_SIZE, 
      DestinationTableName = TableName4 
     }; 

     table4BulkCopy.WriteToServer(table4DataTable); 

     scope.Complete(); 
    } 
} 

Trả lời

7

Move scope.Complete(); ngoài khối connection.

using (var scope = new TransactionScope()) 
{ 
    using (var connection = (SqlConnection)customerTable.OpenConnection()) 
    { 
    // 
    } 
    scope.Complete(); 
} 
+0

Ở đây chi tiết tại sao? Nó là thực hành rất tốt để đặt cuộc gọi như là tuyên bố cuối cùng trong khối sử dụng. [Thông tin thêm về phương pháp] (https://msdn.microsoft.com/es-es/library/system.transactions.transactionscope.complete (v = vs.110) .aspx) – Angel

+1

Nó đã giúp. Cảm ơn allot –

85

Tôi biết điều này là muộn, nhưng có lẽ nó sẽ giúp người khác.

Điều này có thể xảy ra khi giao dịch hết giờ. Bạn có thể tăng thời gian chờ cho giao dịch của bạn như thế này (sử dụng các giá trị phù hợp với thời lượng giao dịch dự kiến ​​của bạn). Đoạn code dưới đây là dành cho 15 phút:

using (TransactionScope scope = 
      new TransactionScope(TransactionScopeOption.Required, 
            new System.TimeSpan(0, 15, 0))) 
    { 
     // working code here 
    } 

Đây là lý do tại sao nó có thể làm việc cho batchsize 500 và không cho 1000.

+0

Tôi nhận được điều này với 'Timeout = TransactionManger.MaximumTimeout', vì vậy đây không phải là cách duy nhất mà lỗi này có thể xảy ra. –

+0

Câu trả lời này đã khắc phục được sự cố tôi gặp phải. như @Eric J đề cập đến nó không phải là cách duy nhất lỗi này có thể xảy ra, nhưng nếu thời gian giao dịch của bạn ra bạn làm có được thông điệp khá không liên quan ở trên. – b0redom

+0

@Bỏ qua đây là câu trả lời đúng và phải được đánh dấu như vậy. – Kiquenet

17

tôi thấy rằng thiết lập thời gian chờ trong TransactionScope không làm việc cho tôi. Tôi cũng cần thêm khóa cấu hình sau vào cuối thẻ machine.config <configuration> để mở rộng vượt quá thời gian chờ tối đa mặc định là 10 phút.

<system.transactions> 
    <machineSettings maxTimeout="00:30:00" /> <!-- 30 minutes --> 
</system.transactions> 

Credit: http://thecodesaysitall.blogspot.com.au/2012/04/long-running-systemtransactions.html

+0

Lưu ý rằng bạn * phải * đặt nó ở đầu * * của phần cấu hình, nếu không bạn sẽ gặp lỗi từ IIS. –

0

Câu trả lời đầy đủ phải là đầy đủ hơn.

Bạn phải chỉ định - nơi sẽ được thời gian chờ giao dịch tối đa xác định - trong mã Net, hoặc trong máy chủ cấu hình

<sectionGroup name="system.transactions".... 
    ...allowDefinition="MachineOnly" 
</sectionGroup> 

Trong trường hợp này bạn có thể thiết lập thời gian chờ tối đa trong machine.config

<configuration> 
<system.transactions> 
<machineSettings maxTimeout="01:00:00" /> 
</system.transactions> 
</configuration> 

Hoặc có thể bạn muốn ghi đè hành vi này trong ứng dụng. Sau đó trong machine.config bạn nên đặt atribute các velue:

...allowDefinition="MachineToApplication" 

Đây là một arcticle tốt: https://blogs.msdn.microsoft.com/ajit/2008/06/18/override-the-system-transactions-default-timeout-of-10-minutes-in-the-code/

Các vấn đề liên quan