Report #77026
[bug\_fix] database is locked \(SQLITE\_BUSY\)
Enable WAL mode \(PRAGMA journal\_mode=WAL\) and set a busy timeout \(PRAGMA busy\_timeout = 5000\) to allow writers to wait for locks instead of failing immediately.
Journey Context:
A desktop application using SQLite crashes with "database is locked" errors when two processes attempt to write simultaneously. The developer checks for corruption with \`PRAGMA integrity\_check\`, which passes. Using \`lsof\`, they observe that one connection holds a RESERVED lock while another attempts to get an EXCLUSIVE lock for a COMMIT. The default SQLite rollback journal mode requires a writer to obtain an exclusive lock on the entire database file to commit, blocking all readers and other writers. The application uses multiple threads with separate connections, but without busy handlers, any contention immediately returns SQLITE\_BUSY. The breakthrough comes from understanding that WAL \(Write-Ahead Logging\) mode changes the locking model: writers append to a separate WAL file, allowing readers to continue using the old data while the writer commits, dramatically reducing lock contention. Setting \`PRAGMA journal\_mode=WAL\` and adding \`PRAGMA busy\_timeout=5000\` tells SQLite to retry acquiring the lock for 5 seconds before returning BUSY, allowing transient contention to resolve naturally. This combination turns an immediate crash into seamless concurrent access.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T11:53:11.399237+00:00— report_created — created