簡體   English   中英

Sqlite數據庫已鎖定

[英]Sqlite database locked

我正在使用asp.net c#並將SqLite數據庫上傳到服務器,然后我做了一些插入和更新。 問題是,有時候(我認為當更新時出現問題時)數據庫會被鎖定。 因此,下次我再次嘗試上傳文件時,它會被鎖定,並且我收到一條錯誤消息,指出“該進程無法訪問該文件,因為它正被另一個進程使用”。 如果在交易過程中出現問題,可能不會處理數據庫文件? 解決此問題的唯一方法是重新啟動服務器。

如何在我的代碼中解決它,以便我可以確定即使出現問題也始終解鎖?

這是我的代碼:

try
{
  string filepath = Server.MapPath("~/files/db.sql");

  //Gets the file and save it on the server
  ((HttpPostedFile)HttpContext.Current.Request.Files["sqlitedb"]).SaveAs(filepath);

  //Open the database
  SQLiteConnection conn = new SQLiteConnection("Data Source=" + filepath + ";Version=3;");

  conn.Open();
  SQLiteCommand cmd = new SQLiteCommand(conn);
  using (SQLiteTransaction transaction = conn.BeginTransaction())
  {
     using (cmd)
     {
        //Here I do some stuff to the database, update, insert etc
     }
     transaction.Commit();
  }
  conn.Close();
  cmd.Dispose();
}
catch (Exception exp)
{
//Error
}

您也可以嘗試將Connection放在using塊中,或者在其上調用Dispose:

//Open the database
using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + filepath + ";Version=3;")) {
  conn.Open();
  using (SQLiteCommand cmd = new SQLiteCommand(conn)) {
    using (SQLiteTransaction transaction = conn.BeginTransaction()) {
      //Here I do some stuff to the database, update, insert etc
      transaction.Commit();
    }
  }
}

這將確保您正確處理連接對象(此時您還沒有關閉它)。

將它們包裝在使用塊中可確保即使發生異常也會調用Dispose - 它實際上與寫入相同:

// Create connection, command, etc objects.
SQLiteConnection conn;

try {
  conn = new SQLiteConnection("Data Source=" + filepath + ";Version=3;");
  // Do Stuff here...
}
catch (exception e) {
  // Although there are arguments to say don't catch generic exceptions,
  // but instead catch each explicit exception you can handle.
}
finally {
  // Check for null, and if not, close and dispose
  if (null != conn)
    conn.Dispose();
}

無論異常如何,都會調用finally塊中的代碼,並幫助您清理。

asp.net應用程序在服務器中是多線程的。

您無法同時寫入(插入,選擇,更新...),因為整個數據庫已被鎖定。 當沒有寫入時,允許同時選擇。

您應該使用.NET ReaderWriterLock類: http//msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

你不應該在conn.Close()之前做cmd.Dispose() conn.Close()嗎? 我不知道它是否有任何區別,但您通常希望在初始化順序的相反方向上進行清理。

簡而言之,SQLite處理非托管資源的方式與其他提供程序略有不同。 你必須明確地處理命令(即使你在using()塊之外使用閱讀器,它似乎也能工作。

閱讀此主題以獲得更多風味: http//sqlite.phxsoftware.com/forums/p/909/4164.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM