I use sqlite3
在多线程应用程序中(它是用SQLITE_THREADSAFE=2
)。在观察窗口中我看到sqlite->busyTimeout == 600000
, 我。 e.应该有 10 分钟的超时时间。然而,sqlite3_step
回报SQLITE_BUSY
明显比 10 分钟后快(实际上它立即返回,就像我从未打电话过一样)sqlite3_busy_timeout
)。
这是什么原因sqlite3
忽略超时并立即返回错误?
一种可能性:SQLite 在检测到死锁时忽略超时。
场景如下。交易A
首先作为读取器,然后尝试执行写入。交易B
是一名作家(要么以这种方式开始,要么从读者开始并首先晋升为作家)。B
持有一个RESERVED
锁定,等待读取器清除以便可以开始写入。A
持有一个SHARED
锁(它是一个读者)并尝试获取RESERVED
锁定(这样它就可以开始写入)。有关各种锁类型的说明,请参见http://sqlite.org/lockingv3.html http://sqlite.org/lockingv3.html
在这种情况下取得进展的唯一方法是回滚其中一个事务。再多的等待也无济于事,因此当 SQLite 检测到这种情况时,它不会遵守繁忙超时。
有两种方法可以避免死锁的可能性:
- 切换到WAL mode http://sqlite.org/wal.html- 它允许一名作者与多名读者共存。
- Use
BEGIN IMMEDIATE
启动一个最终可能需要写入的事务 - 这样,它会立即作为写入器启动。这当然会降低系统中潜在的并发性,作为避免死锁的代价。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)