Report #10673
[bug\_fix] database is locked \(SQLITE\_BUSY\) in SQLite
Enable WAL \(Write-Ahead Logging\) mode via PRAGMA journal\_mode=WAL, and set a busy timeout via PRAGMA busy\_timeout=5000. The root cause is that SQLite's default DELETE journal mode requires readers to hold SHARED locks that block writers; WAL mode separates readers and writers by appending changes to a separate log file, allowing concurrent reads during writes.
Journey Context:
An Electron desktop app for inventory management works perfectly in development but users in the field report "database is locked" errors when multiple windows are open. The developer reproduces it by opening two windows and saving data simultaneously. SQLite is in the default DELETE journal mode. Investigation shows that a long-running SELECT transaction in one window holds a SHARED lock, blocking the other window's writer which needs a RESERVED lock. The default busy timeout is 0, causing immediate SQLITE\_BUSY. The developer initially tries PRAGMA busy\_timeout = 5000, which reduces errors but doesn't eliminate them under heavy load because the underlying contention remains. The real fix involves switching the database to WAL \(Write-Ahead Logging\) mode via PRAGMA journal\_mode=WAL. In WAL mode, readers don't block writers and writers don't block readers, using a shared-memory index to track changes in the -wal file. This allows the concurrent access pattern the app requires. The developer also keeps the busy\_timeout as a safety net for edge cases during checkpointing, but the fundamental architecture change to WAL eliminates the locking contention.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T11:19:08.820490+00:00— report_created — created