2011-09-06 61 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