`sqlite3`忽略`sqlite3_busy_timeout`?

Vit*_*lii 2 c c++ sqlite

sqlite3在多线程应用程序中使用(它是用它编译的SQLITE_THREADSAFE=2).在观察窗口中我看到了sqlite->busyTimeout == 600000,即它应该有10分钟超时.然而,sqlite3_step回报SQLITE_BUSY比10分钟之后快得多(它实际上立即返回,就像我从未打过电话一样sqlite3_busy_timeout).什么原因sqlite3忽略超时并立即返回错误?

Igo*_*nik 7

一种可能性:SQLite在检测到死锁时忽略超时.

方案如下.事务A以读者身份开始,后来尝试执行写入.交易B是一个作家(或者以这种方式开始,或者作为读者开始并首先提升为作家).B持有一把RESERVED锁,等待读者清理,以便开始写作.A持有一个SHARED锁(它是一个读者)并试图获取RESERVED锁(因此它可以开始写).有关各种锁类型的说明,请参阅http://sqlite.org/lockingv3.html

在这种情况下取​​得进展的唯一方法是回滚其中一个事务.没有多少等待会有所帮助,因此当SQLite检测到这种情况时,它不会遵循忙碌超时.

有两种方法可以避免死锁的可能性:

  1. 切换到WAL模式 - 它允许一个作者与多个读者共存.
  2. 使用BEGIN IMMEDIATE启动一个事务,最终可能需要写-这种方式,它开始作为一个作家的时候了.这当然会降低系统中潜在的并发性,因为避免死锁的代价.