On Mon, Apr 02, 2012 at 07:40:58PM +0400, Gregory Petrosyan scratched on the 
wall:
> Hello,
> 
> I am experiancing a weird problem: sometimes (1 time in a 10-100) when
> 2 processes try to open the same database file (and execute something
> like 'create table foo if not exists'), one of them fails with
> SQLITE_BUSY ??? despite 1 second (or bigger) timeout.
> 
> Processes themselves produce almost no DB activity; they merely start
> and initialize the database roughly at the same time.
> sqlite3_open_v2() is immediately followed by sqlite3_busy_timeout().
> 
> Unfortunately I can't write a small program that reproduces this
> reliably: my test program never crashes this way (except when timeout
> is really small ??? say, 10ms). Yet, this behaviour is rare but
> reproducible, both from Python (apsw) on Windows, Python (apsw) on OS
> X and native C API on OS X (in entirely different program).
> 
> Can you please point me at what can be the cause of this?

  You may be seeing a deadlock situation.  This is most commonly
  associated with explicit transactions (that are open for a longer
  period of time), but it is possible with implicit transactions.
  
  If two connections attempt to write to the DB at the same time, it is
  possible for them to deadlock on the file locking.  SQLite recognizes
  this and has one of the connections back off with an SQLITE_BUSY error.
  If this happens in an explicit transaction, the program needs to
  ROLLBACK the current transaction and start over.  In the case of an
  implicit transaction around a statement, you can safely re-run
  the statement.

     http://sqlite.org/c3ref/busy_handler.html 

     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 or SQLITE_IOERR_BLOCKED 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.


   -j


-- 
Jay A. Kreibich < J A Y  @  K R E I B I.C H >

"Intelligence is like underwear: it is important that you have it,
 but showing it to the wrong people has the tendency to make them
 feel uncomfortable." -- Angela Johnson
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to