2013-09-27 35 views
3

我有一個循環插入記錄到數據庫(火鳥):添加事務範圍,以Parallel.Foreach

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options)) 
{ 
    taskList.Add(Task.Factory.StartNew(() => 
    {  
     Parallel.ForEach(objectList, c => 
     { 
      DoInsert(c, id); 
     }); 
    })); 

    scope.Complete() 
} 

我想如果插入失敗回滾這些插入作爲一個批次的能力。但是,當我在Parallel.Foreach循環中執行插入操作時,事務範圍不可見。我假設這是因爲循環在不同的線程中運行。如果我使用TransactionScope作爲串行插入操作,則一切正常。

我試過使用DependentTransaction,但我似乎無法獲取上下文到DoInsert函數。 DoInsert只是打開一個連接並將C的內容寫入數據庫。

任何想法?

感謝,

+0

是不是將TransactionScope綁定到Connection? –

+0

@JeroenvanLangen,不,你正在考慮[SqlTransaction](http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.aspx),[TransactionScope](http:// msdn。 microsoft.com/en-us/library/system.transactions.transactionscope.aspx)是不同的。 –

回答

5

使用單一的TransactionScope,你提到的原因,你不能做到這一點:TransactionScope的依賴於ThreadLocal的存儲,而你是在多線程環境。

但更重要的是,爲此,每個工作線程都需要打開一個連接,在分佈式事務中登記它,執行插入並關閉連接。

如果這是簡單的插入,我會很驚訝,創建所有這些連接會給你任何性能優勢。事實上,我相信如果你在單線程和單一連接上完成這個程序,速度會更快。顯然,這意味着連接打開(關閉)一次,並作爲參數傳遞給DoInsert方法。

更好的是,你可能想看看批量插入。