2016-07-05 134 views
2

我的代碼有問題。 我想刪除我的SQLite數據庫中的一些行,但我得到一個「數據庫被鎖定」異常。 我讀了幾篇文章,比如this post,但我的問題仍然存在。用SQLite和C「數據庫被鎖定」#

這裏是我的代碼:

using (var c = new SQLiteConnection(_connectionSQLite)) 
{ 
    c.Open(); 

    if (c.State == ConnectionState.Open) 
    { 
     var reqExist = string.Concat("SELECT id FROM ... "); 
     using (var cmdExist = new SQLiteCommand(reqExist, c)) 
     { 
      var reqUpdate = string.Concat("UPDATE ... WHERE id = ", cmdExist.ExecuteScalar()); 

      using (var cmdUpdate = new SQLiteCommand(reqUpdate, c)) 
      { 
       cmdUpdate.ExecuteNonQuery(); 
      } 
     } 
    } 

    c.Close(); 
} 

我得到的「數據庫被鎖定」異常就行了cmdUpdate.ExecuteNonQuery();。我試着用DELETE FROM替代,結果相同,但是用SELECT,它工作正常,我真的不明白我的代碼有什麼問題。

感謝您的任何幫助。

+3

@AbhilashRVankayala - 這是可怕的建議。嵌套使用語句沒有任何問題,並且這種語句(或者equiv try-finally)對於確保恰當的資源處置是必要的 - 這是他們問題的一個原因。 – antiduh

+0

你是否同時打開多個連接到同一個數據庫? –

+0

如果ExecuteScalar沒有找到任何id,會發生令人討厭的事情。這似乎是一個聰明的想法,以concat ExecuteScalar的回報,但......。 – Steve

回答

1

您正試圖在處理第一個命令之前運行第二個命令。當您嘗試運行cmdUdpdate時,cmdExist可能會鎖定數據庫。

您應該重構您的代碼,以便您的命令的using塊不會嵌套。

Does SQLite lock the database file on reads?似乎表明你可以閱讀然後寫,所以我也要確保你沒有從其他地方打開數據庫。它似乎仍然是可能的罪魁禍首。

+0

我將每個請求分開,但我仍然遇到問題,即使在每個命令之後進行處理。 – BlackAlpha

+0

感謝您的回答,我爲我的命令嵌套使用塊,它讓我發瘋,並且您的答案也有所幫助。 – Brcinho

0

儘量簡化你的選擇然後更新到聲明是這樣的:

UPDATE ... WHERE ID =(SELECT ID FROM ...)

如果成功,那麼你就知道失敗的原因是select和update之間的交互 ​​- 也就是說,單獨的select必須在數據庫上保存一個打開的共享鎖,以便更新運行。

如果由於鎖定的數據庫導致此組合語句失敗,那麼您知道其他內容阻止更新 - 而不是選擇。應用程序中還有其他內容導致數據庫鎖定失敗。

4

好的,謝謝你的幫助。 我只需在插入/更新之前在其他函數中配置()兩個閱讀器,它就可以工作!