我正在使用 System.Data.Sqlite 在 C# 中访问 SQLite 数据库。我有一个查询必须通读表中的行。在遍历行和阅读器打开时,必须执行某些 SQL 更新。我遇到了“数据库已锁定”异常。
SQLite 文档指出:
当进程想要从数据库文件中读取数据时,它遵循以下步骤顺序:
- 打开数据库文件并获得一个共享锁。
该文档进一步说明了“共享”锁定:
数据库可以被读取但不能被写入。任意数量的进程可以同时持有 SHARED 锁,因此可以有许多同时读取者。但是当一个或多个共享锁处于活动状态时,不允许其他线程或进程写入数据库文件。
常见问题解答指出:
多个进程可以同时打开同一个数据库。多个进程可以同时执行 SELECT。但是,任何时候只有一个进程可以对数据库进行更改。
《SQLite 权威指南》一书指出:
...通过使用read_uncommited pragma ,连接可以选择具有未提交读隔离级别。如果设置为true,则连接不会在它读取的表上设置读锁。因此,另一个写入者实际上可以更改表,因为处于未提交读模式的连接既不会阻塞也不会被任何其他连接阻塞。
我试图将编译指示设置为在 SQL 查询命令语句中读取未提交,如下所示:
PRAGMA read_uncommitted = 1;
SELECT Column1, Column2 FROM MyTable
使用不同连接在同一线程上进行 SQL 更新仍然失败,并出现“数据库已锁定”异常。然后我尝试将隔离级别设置为在连接实例上读取未提交。仍然没有变化,同样的例外。
如何让开放数据阅读器在不锁定数据库的情况下循环遍历数据库中的行,以便执行更新?
更新:
下面的两个答案都有效。然而,我已经从使用默认回滚日志转移到现在使用预写日志记录,它提供了改进的数据库读取和写入并发性。