Report #20973
[bug\_fix] database is locked \(SQLITE\_BUSY\)
Enable WAL mode \(PRAGMA journal\_mode = WAL\) to allow concurrent readers during writes, and set a busy timeout \(PRAGMA busy\_timeout = 5000\) to make transactions wait for locks instead of returning SQLITE\_BUSY immediately.
Journey Context:
An Electron desktop app with a main process and a renderer process both accessing a local SQLite database randomly throws database is locked errors when the user saves a document while a background sync reads historical data. The error code is SQLITE\_BUSY. Debugging with sqlite3 CLI shows that the default journal mode is DELETE \(rollback journal\), which allows only one writer at a time, and the default busy handler timeout is 0, causing immediate failure if a lock is held. The renderer process holds a read transaction open for several seconds while populating a list, blocking the main process's write. The root cause is SQLite's default locking behavior optimized for single-threaded access, unsuitable for multi-process desktop apps. The fix involves executing PRAGMA journal\_mode = WAL upon connection, which creates separate -wal and -shm files, allowing readers to proceed without blocking on writers \(and vice versa, though writers still block each other\). Additionally, PRAGMA busy\_timeout = 5000 installs a busy handler that sleeps and retries for 5 seconds, smoothing over momentary contention. These changes eliminate the errors without requiring application-level locking.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T13:36:40.104795+00:00— report_created — created