如何使用数据读取器执行SQLite查询而不锁定数据库?

Ela*_*lan 11 c# sqlite locking system.data.sqlite

我正在使用System.Data.Sqlite访问C#中的SQLite数据库.我有一个查询必须读取表中的行.在遍历行并且在阅读器打开时,必须执行某些SQL更新.我遇到了"数据库被锁定"异常.

SQLite的文档状态:

当进程想要从数据库文件中读取时,它遵循以下步骤:

  1. 打开数据库文件并获取SHARED锁.

文档进一步说明了"共享"锁定:

可以读取数据库但不写入数据库.任意数量的进程可以同时保存SHARED锁,因此可以有许多同时读取器.但是,当一个或多个SHARED锁处于活动状态时,不允许其他线程或进程写入数据库文件.

常见问题状态:

多个进程可以同时打开同一个数据库.多个进程可以同时执行SELECT.但是,只有一个进程可以随时对数据库进行更改.

SQLite权威指南一书指出:

... 通过使用read_uncommited编译指示,连接可以选择具有读取未提交的隔离级别.如果设置为true,则连接不会对其读取的表放置读锁定.因此,另一个writer实际上可以更改表,因为read-uncommitted模式下的连接既不会阻塞也不会被任何其他连接阻塞.

我尝试将pragma设置为在SQL查询命令语句中读取未提交,如下所示:

PRAGMA read_uncommitted = 1;
SELECT Column1, Column2 FROM MyTable
Run Code Online (Sandbox Code Playgroud)

使用不同连接在同一线程上的SQL更新仍然失败,并出现"数据库已锁定"异常.然后,我尝试将隔离级别设置为在连接实例上读取未提交.同样的例外仍然没有变化.

如何在不锁定数据库的情况下使用开放数据读取器来遍历数据库中的行,以便我可以执行更新?

更新:

以下两个答案都有效.然而,我已经从使用默认回滚日志转移到现在使用预写日志,这提供了改进的数据库读写并发性.

Dou*_*rie 8

使用WAL模式.

  • 使用System.Data.SQLite.Core,您可以通过在连接字符串中添加"journal mode = Wal"来完成此操作 (2认同)