Use SQLite in WAL mode, with IMMEDIATE transactions #412
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
WAL mode is generally better, and allows concurrent reads to happen concurrently with other reads and writes. It does not allow writes concurrently with writes, though, failing with SQLITE_BUSY if that occurs.
SQLite's
busy_timeout
allows retrying on SQLITE_BUSY, but that does not work if a read-only transaction is upgraded to a write transaction, which is whatTransactionBehavior::Deferred
(a.k.a.BEGIN DEFERRED
) does.TransactionBehavior::Immediate
always begins a write transaction immediately, fails with SQLITE_BUSY if that is not allowed, and uses thebusy_timeout
logic to try to wait for the running transaction to finish.This includes a unit test, but as the issue is a race condition, the test does not always fail without the fix. However, it reliably passes with the fix, which is really the important bit.
This fixes GothenburgBitFactory/taskwarrior#3325.