Not sure if this is the problem you are running into, but it might be because
SQLite is detecting a potential deadlock. When you just use BEGIN, SQLite
will acquire locks lazily - the first read operation will acquire a shared
lock, and the first write operation will acquire a reserved lock. Any number
of connections can hold a shared lock, but only one can hold a reserved lock
- all others will get back SQLITE_BUSY and have to wait. Furthermore, to
actually commit a write transaction, it has to wait for all pending shared
locks to be released.

Consider the following situation:
1. Connection A begins a transaction. No locks acquired yet.
2. Connection B begins a transaction. No locks acquired yet.
3. Connection A reads from the database. It acquires a shared lock.
4. Connection B begin a transaction. No locks acquired yet.
5. Connection B writes to the database It acquires a reserved lock.
6. Connection A writes to the database. It tries to acquire an exclusive
lock. But connection B already has one. Presumably, connection B would try
to actually commit to the database at some point. But doing so would require
it to wait for all shared locks to be released. Connection A is holding a
shared lock. So now we could have a deadlock - A is waiting for B so it can
acquire a reserved lock, and B is waiting for A so it can acquire an
exclusive lock. SQLite detects this and connection A immediately returns
SQLITE_BUSY, bypassing any busy timeout or busy handler.

To avoid this issue, use "BEGIN IMMEDIATE" instead of "BEGIN". This makes it
so the writer immediately acquires a reserved lock. Since it jumps directly
there instead of acquiring a shared lock first, there's no deadlock
potential, so the busy timeout will actually be respected.



--
Sent from: http://sqlite.1065341.n5.nabble.com/
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to