C# - 如何检测 SQLite DB 是否被锁定?

2024-05-06

我正在开发一个使用 SQLite 的多线程 C# 程序。我遇到一个问题,有时运行 SQLiteCommand.ExecuteNonQuery() 来更新某些行会抱怨“SQLite 错误 (5):数据库已锁定”。我知道发生这种情况是因为数据库在插入或更新时被锁定,因此如果出现另一个修改数据库的查询,第二个查询将出现此数据库被锁定错误。所以我正在尝试实施解决方法,但我不确定应该如何做。

我试图做到这一点,以便如果抛出数据库锁定错误,则程序会等待一段时间并再次尝试,直到它起作用。但不知何故,没有捕获异常,并且代码只是退出 try-catch 块,即使数据库锁定消息仍然打印在调试输出中。我不完全确定 SQL 查询是否被拒绝或接受。

我也尝试过使用 TransactionScope,从那时起我就没有遇到过数据库被锁定的情况,但是由于问题的随机性,我无法 100% 确定 TransactionScope 是否真正解决了问题,或者它是否只解决了问题程度,或者如果没有,到目前为止我很幸运。

SQLiteConnection connection = new SQLiteConnection("Data Source=DB.db;Version=3;");
connection.Open();
SQLiteCommand command = connection.CreateCommand();
command.commandText = inputQuery;
try
{
  command.executeNonQuery();
}
catch (SQLiteException sqle)
{
  Debug.WriteLine("Database error: " + e.Message);
  return false;
}
catch (Exception e)
{
  Debug.WriteLine("Database error: " + e.Message);
  return false;
}
finally
{
  connection.Close();
}

所以我真的很希望有人帮助我找出 1)如何消除数据库被锁定问题或 2)如何检测数据库是否被锁定错误发生。提前致谢。


为了检测 Sqlite DB 是否被锁定,我使用了以下方法判断SQLite数据库是否被锁定 https://stackoverflow.com/questions/57744538/determine-whether-sqlite-database-is-locked#这里的想法是尝试获取锁并立即释放它,如果没有失败则数据库没有被锁定。 以下 C# 代码对我有用:

public bool IsDatabaseLocked(string dbPath)
    {
        bool locked = true;
        SQLiteConnection connection = new SQLiteConnection($"Data Source={dbPath};Version=3;");
        connection.Open();
        
        try
        {
            SQLiteCommand beginCommand = connection.CreateCommand();
            beginCommand.CommandText = "BEGIN EXCLUSIVE"; // tries to acquire the lock
            // CommandTimeout is set to 0 to get error immediately if DB is locked 
            // otherwise it will wait for 30 sec by default
            beginCommand.CommandTimeout = 0; 
            beginCommand.ExecuteNonQuery();

            SQLiteCommand commitCommand = connection.CreateCommand();
            commitCommand.CommandText = "COMMIT"; // releases the lock immediately
            commitCommand.ExecuteNonQuery();
            locked = false;
        }
        catch(SQLiteException)
        {
            // database is locked error
        }
        finally
        {
            connection.Close();
        }

        return locked;
    }

然后,当您确定数据库是否被锁定时,您可以等待它被解锁:

public async Task WaitForDbToBeUnlocked(string dbPath, CancellationToken token)
    {
        while (IsDatabaseLocked(dbPath))
        {
            await Task.Delay(TimeSpan.FromSeconds(1), token);
        }
    }

或者在运行查询之前将取消消息发送到其他线程(例如通过 CancellationTokenSource)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# - 如何检测 SQLite DB 是否被锁定? 的相关文章

  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 打破 ReadFile() 阻塞 - 命名管道 (Windows API)

    为了简化 这是一种命名管道服务器正在等待命名管道客户端写入管道的情况 使用 WriteFile 阻塞的 Windows API 是 ReadFile 服务器已创建启用阻塞的同步管道 无重叠 I O 客户端已连接 现在服务器正在等待一些数据
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • C++ 中的双精度型数字

    尽管内部表示有 17 位 但 IEE754 64 位 浮点应该正确表示 15 位有效数字 有没有办法强制第 16 位和第 17 位为零 Ref http msdn microsoft com en us library system dou
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐