2017-06-16 41 views
0

我有以下的基本OLEDB循環:C#我應該在for循環之外放置Sql/OleDb transaction.Commit()嗎?

using (OleDbConnection conn = new OleDbConnection(Con)) 
{ 
    using (OleDbCommand cmd = new OleDbCommand()) 
    { 
     for loop 
     { 
     cmd.Connection = conn; 
     conn.Open(); 
     transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted); 
     cmd.CommandText = "row by row insert" 
     cmd.Some parameters, then ExecuteNonQuery 
     transaction.Commit(); 
     } 
    } 
} 

但是,我不能肯定我是否應該命令執行後放置Commit內環路。我說完之後應該把它放置嗎?大綱using將是try catch包含回滾在catch。所以我猜如果我想能夠回滾所有的更改,我會希望循環完全運行,然後提交它?

我也剛剛瞭解到TransactionScope s,它概述了使用中的SQL上下文,所以我想知道它是如何應用於此的。

+1

取決於您的要求。所有INSERT命令是否應該在出現故障時重置? – jAC

+0

是的,我想這是對的。因此,如果它在循環中,最大的捕獲量將會回滾到最後一行?此外,我試圖使用TransactionScope,我添加了參考和這樣的,我認爲這將適用於任何數據庫不可知的平臺?因爲我沒有看到任何地方可以定義它。 @JanesAbouChleih – Arvayne

+1

確切地說,你的代碼現在只會重置最後一個'INSERT'的事務。如果你把它放在循環之外(當然用'conn.BeginTransaction(IsolationLevel.ReadCommitted);')它會重置在這個事務/ for循環中處理的所有'INSERT'命令。 但是現在,在處理'transaction.Rollback()'的時候,仍然有一些異常處理丟失。 €:由於@Mike Nakis已經聲明它對db的性能有很大的影響,因爲所有的交易都被記錄下來。因此交易次數越少=性能越快。我不明白'TransactionScope'問題。 – jAC

回答

2

BeginTransaction()調用位於循環內時,您無法將Commit()呼叫移動到循環外部。兩者都會留在循環中,或者兩者都會在循環之外。

所以,你的問題應該是:「我應該每循環執行一次事務,還是應該開始事務,執行循環,然後執行事務?」

那麼,每次迭代執行一次事務的唯一原因是非常不可能發生的情況,您希望即使其中一些失敗,也要提交所有非失敗的插入。 (在這種情況下,您還需要執行一些異常處理。)

如果您沒有這樣的要求,並且如果您不介意數量級的性能改進,那麼您最好啓動一個事務,做你的循環,然後關閉你的交易。