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.?