On Thu, Aug 19, 2010 at 07:54:19PM +0100, Simon Slavin scratched on the wall:
> I don't know what you mean by 'cursor'. SQLite has commands. You > execute one command at a time. Even a command like a SELECT that > gathers lots of data gathers the data all in one go, then finishes. None of this is true for the API. You are more than able to have multiple statements "in flight" at the same time (I don't mean "prepared", I mean actually executing). SELECT does not give the data in one go, but returns it one row at a time. You can have calls to sqlite3_step() that reference multiple statements inter-mixed with each other. > SQLite does not mark its place with one command, then return to that > place again with another command. Actually, that is *exactly* what prepared statements do each time you call sqlite3_step(). > SQLite never locks individual > records, it only every locks the entire database file in various ways. OK, that's almost true. > > - Is there a way to prevent SQLite from keeping the SHARED lock > > while waiting for an EXCLUSIVE lock if doing so would result in a > > deadlock (because another connection holding a SHARED lock needs to > > get an EXCLUSIVE lock before it can release the SHARED lock)? > > SQLite will never know about an impending deadlock, You can't jump directly to the EXCLUSIVE lock, there are steps. But, yes, SQLite auto-detects this dead-lock situation and has the connection that does not already have the write lock return an SQLITE_BUSY, even if there is an busy-handler in place. It is up to the application to do the right thing, however. 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. In short, you always need to deal with SQLITE_BUSY errors by, sooner or later, backing off and rolling back the current transaction (which should also release all the locks). SQLite puts this responsibility in the hands of the application, however... SQLite will let the application know there is a problem, but it is up to the application to fix it. If you do not respond to a SQLITE_BUSY error, the connections can remain dead-locked. This should never happen between statements using the same connection, however... the locks belong to the connection, not the statements, so two statements using the same connection can never deadlock. -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 [email protected] http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

