繁体   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