Csharp/C#教程:如何在不锁定数据库的情况下使用数据读取器执行SQLite查询分享


如何在不锁定数据库的情况下使用数据读取器执行SQLite查询

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

SQLite文档说明:

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

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

该文档进一步说明了“共享”锁定:

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

FAQ说明:

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

SQLite权威指南一书指出:

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

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

PRAGMA read_uncommitted = 1; SELECT Column1, Column2 FROM MyTable 

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

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

更新:

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

使用WAL模式。

我无法从这里使用开源数据提供程序来实现这一点 。 但是,我能够使用dotConnect的免费标准版如下工作:

创建以下DLL导入,以便我们可以为SQLite启用共享缓存。

 [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int sqlite3_enable_shared_cache(int enable); 

执行上述function以启用共享缓存。 注意,这只需要为整个过程执行一次 – 请参阅SQLite文档 。

 sqlite3_enable_shared_cache(1); 

然后使用pragma语句为数据读取器使用的SQL查询语句添加前缀,如下所示:

 PRAGMA read_uncommitted = 1; SELECT Column1, Column2 FROM MyTable 

现在可以在数据读取器处于活动状态时自由更新和插入行。 可以在此处找到有关共享缓存的其他SQLite文档。

更新:

较新版本的Devart SQLite数据提供程序现在以改进的方式支持此function。 要启用共享缓存,可以进行以下调用:

 Devart.Data.SQLite.SQLiteConnection.EnableSharedCache(); 

可以将未提交的读取配置到连接字符串中,例如,如下所示:

上述就是C#学习教程:如何在不锁定数据库的情况下使用数据读取器执行SQLite查询分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

 Devart.Data.SQLite.SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(); builder.ReadUncommitted = true; builder.DateTimeFormat = Devart.Data.SQLite.SQLiteDateFormats.Ticks; builder.DataSource = DatabaseFilePath; builder.DefaultCommandTimeout = 300; builder.MinPoolSize = 0; builder.MaxPoolSize = 100; builder.Pooling = true; builder.FailIfMissing = false; builder.LegacyFileFormat = false; builder.JournalMode = JournalMode.Default; string connectionString = builder.ToString(); 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/953921.html

(0)
上一篇 2021年11月19日
下一篇 2021年11月19日

精彩推荐