阻止sqlite步骤,直到数据库不再忙

时间:2015-08-26 01:10:01

标签: c++ sqlite

在C ++中使用sqlite库时,sqlite3_stmt上对SQLITE_BUSY的调用可能会以多种不同方式失败。据我所知,除了一个之外,所有这些都应该导致异常,或者是由编程错误引起的。

然而,有一点让我感到困惑:SQLITE_BUSY。我的意思是:sqlite3_step只是意味着数据库被锁定,因为某些事务已经发生在它上面,对吗?假设某个不同的进程已经开始一个事务并且还没有提交或发布它,对SQLITE_BUSY尝试编辑数据库或开始新事务的任何调用都将失败并显示sqlite3_step_or_block_until_available_then_step(my_stmt);

但是,这对我来说并不是一个错误:当使用资源时,我可以......等等!与互斥体(可能更复杂的性质)不同,我想,应该可以阻止当前线程/进程的执行,直到再次可以访问共享资源。

有没有办法做这样的事情?我想要的是形式:

SQLITE_BUSY

因此执行被阻止,直到数据库不再繁忙,我可以使用它。是否有sqlite库本身提供的解决方案?如果没有,我该怎么办?我的意思是,我显然可以忙着等到{{1}}错误不再返回,但它并没有真正意义,因为它消耗了大量资源。是否有更多表现方式来实现这一目标?

如果可能,请提供一些简短示例,以便我了解如何使其发挥作用!

1 个答案:

答案 0 :(得分:1)

您可以使用互斥锁自行锁定数据库,但sqlite3执行provide a mechanism that might help(强调我的):

  

SQLITE_BUSY
  SQLITE_BUSY结果代码表示由于某些其他数据库连接的并发活动(通常是单独进程中的数据库连接),无法写入(或在某些情况下读取)数据库文件。
  例如,如果进程A处于大型写入事务的中间,同时进程B尝试启动新的写入事务,则进程B将返回SQLITE_BUSY结果,因为SQLite一次只支持一个编写器。在开始新事务之前,进程B需要等待进程A完成其事务。 处理B可以使用sqlite3_busy_handler()busy_timeout pragma接口以及SQLITE_BUSY来帮助它处理SQLITE_BUSY错误。

您可以register a callback to handle SQLITE_BUSY,而不是返回std::mutex的数据库,它将调用您的处理程序。您可以在链接中阅读这些限制。

我不会为此提供一个示例,因为我觉得解决having multiple threads access a database问题的可能性较小,因为每个数据库连接只能有一个繁忙的处理程序。

如果我怀疑来自your previous question,您可以控制访问数据库的所有代码,那么可能更容易使用std::conditional_variable{ std::lock_guard<std::mutex> lock(dbMutex); sqlite3_stmt(...); }

{{1}}