I wrote an article about my high-level understanding of `SQLITE_BUSY` errors, hoping it might help others understand concurrency in SQLite better. It covers scenarios under which the error shows up, while SQLite tries to respect its isolation guarantee.
I read your article, though I did not go through all the logic and check that it is correct. I like your choice of sections, and found your diagrams to be clear. I have three points:
First, you include in your article several direct quotes from the SQLite documentation. It is an error to include these without labelling them as such. I see that in one case you write "From its documentation". Including "From SQLite's documentation" each time you quote from it would correct this problem.
Second, there are a few places where you have used just the acronym "WAL" where I would have expected you to put "WAL mode", to remind the reader that SQLite has another mode and they need to explicitly set WAL mode if they want it.
My third point would be relating to setting a timeout. You mention setting a busy timeout late in the article, and as part of the deadlocks section, and your text jumps straight to the most complicated way of doing it: supplying your own busy handler. This misses a more important and easier aspect.
Your article is a good overview of the subject, written for those who have studied computer science. But it would be far more useful to programmers who have just encountered SQLITE_BUSY if near the beginning you mention one or both of
which sets a timeout time, and tells SQLite to use its own timeout handler, rather than the programmer having to supply one. Setting this to a few thousand milliseconds, means that most SQLite programmers never see a result of SQLITE_BUSY, without supplying a busy-handler routine, and without including complicated and difficult-to-debug retry-loops in their code. It covers all busy situations, not just deadlock, and I feel that it's important to any discussion of SQLITE_BUSY.