2011-09-06 104 views
1

我必須更新一些DataTable,我將它作爲XML發送數據。如果出現問題,我的存儲過程有事務中止操作。但是我必須更新的記錄數量非常大,XML達到35 MB +。它只是在開發中,而且實時數據會更大。任務,TransactionScope和SQL Server存儲過程

爲了處理這個問題,我想通過塊發送數據進行更新,也就是說,我一次會發送數百條記錄的XML。我試圖使用Task庫來像這樣並行更新數據庫。

var ret=0; 
using(var ts = new TransactionScope(TransactionScopeOption.Required, 
                 new TimeSpan(2,0,0)) 
{ 
    try 
    { 
     for(some condition) 
     { 
      get chunk of records 
      generate xml 
      create new task and call routing to push data to db 
      var t = create new task and call routing to push data to db 
      tasks.Add(t); 
     } 

     Task.WaitAll(tasks.ToArray()); 
     ts.Complete(); 
     foreach(var t in tasks) 
      ret += t.Result; 
    } 
    catch(Exception ex) 
    { 
     //log exception and show user message 
    } 
} 
return ret; 

但我得到異常事務已被中止。

我需要做什麼來完成單個事務中的更新,因爲如果任何塊無法正確更新,我必須回滾任何更改。

編輯: - 我使用new TransactionScope(TransactionScopeOption.Required,new TimeSpan(2,0,0))勵科普塞的建議,但即使一個調用數據庫,在2-3秒完成後,仍然收到錯誤System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout

只有一個呼叫

+0

'WaitForAll'不上'Task'的方法 - 你可以把你的真實代碼? –

+0

@Reed Copsey真正的代碼在辦公室:D該方法是'Task.WaitAll'。 – TheVillageIdiot

回答

1

你需要等待,直到完成任務調用ts.Complete()之前。這看起來更像是:

using(var ts = new TransactionScope()) 
{ 
    try 
    { 
     List<Task> tasks = new List<Task>(); 

     for(some condition) 
     { 
      // get chunk of records 
      // generate xml 
      // create new task and call routing to push data to db 
      var task = PushDataAsync(theData); // make the task 
      tasks.Add(task); // Keep a reference in a collection 
     } 

     // Wait until all tasks are done, so you can complete the transaction... 
     // If any task raises an exception, you'll get an AggregateException here 
     Task.WaitAll(tasks.ToArray()); 

     ts.Complete(); 
    } 
    catch(Exception ex) 
    { 
     //log exception and show user message 
    } 
} 
+0

我已經這樣做了。請參閱我的編輯。 – TheVillageIdiot

+0

@TheVillageIdiot:這應該工作 - 你是'TransactionScope'超時?這會導致它在您處理時中止,可能... –

+0

明天我會得到確切的異常並更新問題。但是如果'TransactionScope'超時,我有什麼選擇? – TheVillageIdiot

0

你有甚至考慮線程安全?我想知道PushDataAsync裏面有什麼。

TransactionScope不支持跨線程工作。它在內部使用線程本地存儲。範圍屬於單個線程的事實在文檔中明確地被調用。

不知道,如果你真的要在正確的方向,但看看DependentTransaction如果你想在多個線程上的事務協調:http://msdn.microsoft.com/en-us/library/system.transactions.dependenttransaction.aspx