【问题标题】:Multi Threading Safe SQLite多线程安全 SQLite
【发布时间】:2014-07-16 21:52:02
【问题描述】:

我在 Winforms 上的 C# 中有一个类,它不是线程安全的,但我希望它是。取而代之的是SQLite 不断出错说数据库已锁定.. 数据库已锁定..

但是我已经为此计划了:应该有一个 FIFO 队列(这很好)但是这个工作线程(非 gui)正在与 GUI 竞争,因为有一些 gui也需要进入数据库的事件,它们相互碰撞......导致项目失败,然后失控。

我真正想要的只是能够从我需要的任何线程获得 SQLite 连接,并期望它能够保持正常运行。我一直在 MySQL 中做这种事情,近 15 年来从未打过一次..

所以,我的问题是

是否有 a) 有一个简单的等待 SQLite 查询的防弹方法,是否有手动锁定事务的方法(可能在它自己的线程中?)或 b) 是否有一种简单的方法可以强制 SQLite 不存在太挑剔了。有很多 SQL 正在进行,只有当我扩大 Winforms 应用程序时,这些问题才变得明显。我负担不起完全重写。

顺便说一句,我使用这个 DefaultTimeout 来尝试获得一些收益,但这也只是降低了问题阈值,感觉不是最佳的

SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.DefaultTimeout = 200;
builder.DataSource = "some.sqlite";
builder.Version = 3;
conn = new SQLiteConnection(builder.ConnectionString);
conn.Open();

【问题讨论】:

  • 没有理由保持连接打开。打开它,获取您的数据,然后关闭它。
  • 确保在处理完连接和命令后立即处理它们。将它们包装在 using 语句中。
  • @LarsTech 我这样做了,但这没什么区别,因为我正在排队插入并同时从 2 个线程中选择 @Blorgbeard 是的,我会看看 using
  • "应该有一个 FIFO 队列(这很好)但是这个工作线程(非 gui)正在与 GUI 竞争,因为有一些 gui 事件需要去数据库too”——如果 GUI 线程直接进入数据库,那么“one”队列的意义何在?它应该排队查询并等待结果。
  • @Blorgbeard 这显然是我们会有所不同的地方,没有隐含的理由为什么即使十几个并发连接也不能由单个数据库提供服务,它实际上是一个主要结构:在第一原则它与文件系统的区别仅在于它允许并发事务。如果它不能成为数据库,我什至不想要一个数据库。这个奇怪的声明 SQLite“不应该被线程化”“我们这样做是为了让步”是令人震惊的逻辑。它应该只称自己为 FLATFILElite

标签: c# multithreading winforms sqlite


【解决方案1】:

你不能“强迫 SQLite 不要那么挑剔”——它告诉你,如果你做了你想做的事情,就会发生坏事——例如崩溃、数据库损坏或更糟。

我建议您考虑在自己的线程中包装对 SQLite 的访问,然后将其视为具有适当线程可阻塞接口的服务器。尽量避免使用共享资源。在自己的线程上应该使数据库高兴,并且您的其他代码可以根据需要阻止或轮询,直到可以访问为止。作为一个好处,您将获得更多的多核灵活性。

如果您不能这样做,您可以尝试使用“监视器”,有时也称为“同步”调用。但是请注意,这是一条布满陷阱的道路,只有在事件发生后才容易发现。

HTH

【讨论】:

  • 谢谢,换个说法,我可能需要将其编译为线程安全的:如何检查我的 SQLite DLL 版本是否为sqlite.org/threadsafe.html sqlite3_threadsafe() 你知道吗?
猜你喜欢
  • 2022-11-21
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多