Thanks for your response.

On Thu, Jul 9, 2015 at 3:20 PM, Jay Kreibich <jay at kreibi.ch> wrote:

> The sqlite3_busy_timeout() function is just a wrapper for
> sqlite3_busy_handler().
>

?I know that, and I have no? busy_handler installed.



> As explained at http://www.sqlite.org/c3ref/busy_handler.html, the use of
> a busy handler does not avoid all SQLITE_BUSY situations:
> The presence of a busy handler does not guarantee that it will be invoked
> when there is lock contention. If SQLite determines that invoking the busy
> handler could result in a deadlock, it will go ahead and return SQLITE_BUSY
> to the application instead of invoking the busy handler. Consider a
> scenario where one process is holding a read lock that it is trying to
> promote to a reserved lock and a second process is holding a reserved lock
> that it is trying to promote to an exclusive lock. The first process cannot
> proceed because it is blocked by the second and the second process cannot
> proceed because it is blocked by the first. If both processes invoke the
> busy handlers, neither will make any progress. Therefore, SQLite returns
> SQLITE_BUSY for the first process, hoping that this will induce the first
> process to release its read lock and allow the second process to proceed.
>
> Basically, if SQLite detects a dead-lock situation, that no amount of
> waiting will resolve, the busy handlers will immediately return an
> SQLITE_BUSY.  The only way to resolve this situation is for the connection
> to rollback its current transaction, release all locks currently being
> held, and allow the other connection to continue.
>

?I am aware of that, but I'm pretty sure that is not the case. In case of a
deadlock, the unlock notification code returns SQLITE_LOCKED, not
SQLITE_BUSY and the server raises a specific exception for deadlocks.

Also, I neglected to say that all transactions are started with BEGIN
IMMEDIATE, to avoid the lock escalation problem you describe.?

Reply via email to