I use sqlite3
in multiple threads application (it is compiled with SQLITE_THREADSAFE=2
). In watch window I see that sqlite->busyTimeout == 600000
, i. e. that it is supposed to have 10 minutes timeout. However, sqlite3_step
returns SQLITE_BUSY
obvoiusly faster than after 10 minutes (it returns instantly actually, like if I never called sqlite3_busy_timeout
).
What is the reason that sqlite3
ignores timeout and return error instantly?
One possibility: SQLite ignores the timeout when it detects a deadlock.
The scenario is as follows. Transaction A
starts as a reader, and later attempts to perform a write. Transaction B
is a writer (either started that way, or started as a reader and promoted to a writer first). B
holds a RESERVED
lock, waiting for readers to clear so it can start writing. A
holds a SHARED
lock (it's a reader) and tries to acquire RESERVED
lock (so it can start writing). For description of various lock types, see http://sqlite.org/lockingv3.html
The only way to make progress in this situation is for one of the transactions to roll back. No amount of waiting will help, so when SQLite detects this situation, it doesn't honor the busy timeout.
There are two ways to avoid the possibility of a deadlock:
BEGIN IMMEDIATE
to start a transaction that may eventually need to write - this way, it starts as a writer right away. This of course reduces the potential concurrency in the system, as the price of avoiding deadlocks.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With