【问题标题】:Accessing SQLite database from multiple processes and SQLITE_BUSY从多个进程和 SQLITE_BUSY 访问 SQLite 数据库
【发布时间】:2016-07-21 17:20:34
【问题描述】:

我有多个使用相同 SQLite 数据库的进程(c++、Windows 8)。我用SQLITE_CONFIG_SERIALIZEDPRAGMA busy_timeout = 60000; 配置了连接。使用的日志模式 - DELETE

测试场景:

  • 进程 #1 打开连接,进行读/写,休眠 5 秒
  • 进程 #2 打开连接,进行读/写

在该进程 #1 无法写入数据库之后 - 它在调用 SQLite API(sqlite3_step、sqlite3_finalize)后立即收到SQLITE_BUSY。进程 #2 仍然使用连接,没有任何问题。

我没有任何未关闭的事务,我没有对数据库进行任何长时间的操作。还有什么可能导致这种情况?

我在进程内的多个线程中使用相同的 SQLite 连接。 SQLite 文档说配置选项SQLITE_CONFIG_SERIALIZED 可以。这条规则有什么例外吗?

【问题讨论】:

  • 我不确定SQLITE_CONFIG_SERIALIZED 的用处;在我看来,使用它,共享数据库的线程将踩踏彼此的事务。通常这样做的方式是为每个线程提供自己的连接,这具有更合理的语义。

标签: c++ windows multithreading sqlite


【解决方案1】:

SQLite 在sqlite3_prepare 中获取数据库/表的锁定并在sqlite3_finalize 中释放它。锁定类型取决于您的 SQL 表达式。

如果您创建了 STMT - 您需要尽快执行并最终确定。否则你会阻止不同的连接。

我的应用程序创建了准备好的 STMT 列表并将其保留到最后。通常这是对 SQLite 的滥用。

链接:

【讨论】:

  • 很遗憾这是错误的。 sqlite3_prepare 中未获取锁。并且您可以使用sqlite3_reset 来释放锁(当它的准备好的语句被重置或完成时,一个语句结束。 - sqlite.org/lang_transaction.html),所以您不需要尽快sqlite3_finalize
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
  • 1970-01-01
  • 2018-02-14
  • 2012-11-12
  • 2016-12-10
相关资源
最近更新 更多