When a process gets SQLITE_BUSY, it needs to wait for the blocking
operation to finish before it can successfully retry (whether it's
just retrying a COMMIT or redoing a whole transaction).  How do
people typically handle this?

If a different process is the one holding the lock, then you need
to sleep for a while, or sleep(0) to yield the scheduler.  (This
seems to be the case sqlite3_busy_* has in mind.)

However, in a state-engine application where multiple independent
tasks in one thread might have interleaved, "simultaneous" access
to the database, then you need to stash away what you're doing and
let the other tasks run, so the one blocking you can finish.

If you're in a state engine (or Lua coroutines, etc.), it's hard
to tell which of these cases you're in.  If you guess incorrectly,
you'll either chew CPU by not yielding the scheduler, or you'll
yield the scheduler when the blocking task is in the same process.

Both of these can be pretty bad failure modes.  I may end up just
never leaving a transaction unfinished between state engine updates,
so there are never half-finished transactions sitting around holding
locks (guaranteeing that the correct thing to do is sleep).  That's
not good for large, expensive transactions, though, where other
tasks should be given a chance to run.

-- 
Glenn Maynard
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to