2013-08-31 19 views
1
public void test2(String[] users) 
    { 
     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     using (var myTransaction = myDB.BeginTransaction()) 
     { 
      using (cmd = myDB.CreateCommand()) 
      { 
       cmd.Transaction = myTransaction; 
       cmd.CommandText = "UPDATE myTable SET counter = counter + 1 WHERE user = @user"; 
       cmd.Parameters.AddWithValue("@user", ""); 
       foreach (string person in users) 
       { 
        cmd.Parameters["@user"].Value = person; 
        cmd.ExecuteNonQuery(); 
       } 
      } 
      myTransaction.Commit(); 
      stopwatch.Stop(); 
      Console.WriteLine("Updating existing users took: " + stopwatch.Elapsed); 
     } 
    } 

我有一個時間的怪物找出這一個。我查看了大量的c#事務示例,除了具有foreach循環外,我的代碼看起來與所有這些代碼非常相似。但是我在單個事務中看到了多個ExeCuteNonQuery,所以我不知道問題是什麼。任何幫助?SQLite交易拋出異常,我找不出

編輯:想我應該解釋的問題:P

獲取:

"System.ObjectDisposedException: Cannot access a disposed object. Object name: 'SQLiteCommand'."

cmd.Parameters["@user"].Value = person;線。

回答

3

我的猜測是命令在執行後被丟棄。嘗試把foreach外循環:

foreach (string person in users) 
{ 
    using (cmd = myDB.CreateCommand()) 
    { 
     cmd.Transaction = myTransaction; 
     cmd.CommandText = "UPDATE myTable SET counter = counter + 1 WHERE user = @user"; 
     cmd.Parameters.AddWithValue("@user", person); 
     cmd.ExecuteNonQuery(); 
    } 
} 
+0

我真的不想創建一個新的命令(以及與它相關的所有數據),每個循環都通過我的用戶數組,特別是當數組可以是成千上萬的用戶,而我的目標是使用事務來減少數據庫操作的寫入時間。沒有事務處理,任何寫入查詢當前都會採用60-70毫秒的格式。當我一次處理數以千計的用戶時,這是行不通的。試圖優化。 – Keirathi

+0

@Keirathi我相信你正在尋找多行插入,或者你的術語是關閉的。 McGarnagle的答案仍然使用所有插入的交易。如果你想確保只有一個命令被髮送到服務器,請查看http://stackoverflow.com/questions/1609637/is-it-possible-to-insert-multiple-rows-at-a-time-in -an-sqlite-database – Matthew

+0

對不起,我應該在我回答之前測試了他的解決方案。我只是害怕,因爲我在另一篇文章中讀到,只創建一次SQLiteCommand會更好,只綁定一次參數,只設置一次CommandText等等。我擔心這些操作中有超過一個會讓我放慢速度但是10000個操作仍然只需要0.8s,這是合理的操作。標記爲已解決。 – Keirathi

1

它看起來像變量cmd是一個字段。這可以解釋爲什麼可以在foreach循環中處理該命令。如果test2在另一個測試並行運行時運行,則另一個測試可以處理cmd字段中的任何內容。要解決這個問題,請從類中移除cmd,並將其變爲該方法的局部變量。例如,使用(var cmd = myDB.CreateCommand())