Ok, I just had a look at the code
The api sqlite3_busy_timeout
creates a vary naive sqlite3_busy_handler, its implementation is in
sqliteDefaultBusyCallback, what it does is when you get a sqlite_busy
it will sleep for (1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100)
msecs (starting from 1 till 100)
The default handler does not have any smarts about what is going on in seperate threads or the db...
if we remove the sqlit_busy_timeout, and instead implemented some
cross thread comms, and handle sqlite_busy then this can be avoided for
single process apps (further more with global events it could be
resolved for the entire machine)
what i did
1. comment out: int n = UnsafeNativeMethods.sqlite3_busy_timeout_interop(_sql, nTimeoutMS);
2. comment out: UnsafeNativeMethods.sqlite3_sleep_interop((uint)rnd.Next(1, 250));
3. create: internal static AutoResetEvent resetEvent = new AutoResetEvent(false); (on sqlite3.cs)
4. add: resetEvent.WaitOne(rnd.Next(1, 250),true); instead of the sleep interop
5. signal the reset event whenever a transaction is commited
this mostly resolves the stravation issue
whats left to do
1. instead of waiting random times, wait using the following backoff (1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100)
2. create an array of signalling reset events, 1 for each database
3. consider if global signalling is worth looking into
4. register a
sqlite3_commit_hook to handle the signalling
Hope this helps
Cheers
Sam