Igor Tandetnik wrote:
eric-5PSWdYX/[EMAIL PROTECTED] wrote:
I have two threads heavily writing to the db. Hence, I get some
SQLITE_BUSY return values.

If I get it from sqlite3_step(), I wait a few ms and call
sqlite3_step() again etc. This happens in one thread, thread A.

The other thread (thread B) however, is calling the registered busy
handler while executing a commit with an sqlite3_exec() call. And
this is not going away either. even if I let thread A wait forever
(so don't do anything there) thread B is getting SQLITE_BUSY (in
commit with sqlite3_exec()). Both threads are not progressing any
more...

It appears you are getting into a deadlock situation. A deadlock is possible in SQLite in the presence of two writers, where at least one of them peforms a SELECT first before issuing a modifying statement. In this situation, the following scenario may occur:
- thread A begins reading and acquires SHARED lock
- thread B wants to write, acquires PENDING lock and waits for readers to clear.
- thread A now also wants to write and tries to promote to RESERVED lock.

At this point, the two threads wait for each other and neither can proceed. The only way out of this deadlock is for one thread to roll back its transaction and start from the beginning. No amount of waiting will help.

You can avoid the deadlock by having the mixed reader/writer start its transaction with BEGIN IMMEDIATE.
This helps a lot, thanks!
Maybe the documentation should be adapted. The section which explains obtaining locks, does not mention the transaction modifier IMMEDIATE or EXCLUSIVE as a way to obtain a RESERVED lock.


Igor Tandetnik



--
-------------------------------------------
| Eric van der Maarel                     |
| [EMAIL PROTECTED]                        |
-------------------------------------------^[ZZ

Reply via email to