Report #10261
[bug\_fix] database is locked \(SQLITE\_BUSY\)
Root cause: SQLite's default journal\_mode=DELETE uses POSIX file locking; a writer obtains an exclusive lock on the entire database file, causing subsequent readers or writers to receive SQLITE\_BUSY immediately \(or after busy\_timeout\). The definitive fix is to enable WAL \(Write-Ahead Logging\) mode via 'PRAGMA journal\_mode=WAL;'. WAL mode allows concurrent readers to proceed while a writer appends to the WAL file, drastically improving concurrency and eliminating the 'database is locked' error under normal load.
Journey Context:
An Electron-based desktop app used SQLite via better-sqlite3 to store user project data. Users reported 'database is locked' errors when auto-save triggered in one window while another window read from the same DB. Initially tried increasing 'busy\_timeout' to 5000ms, which reduced errors but made the UI hang noticeably. Inspected the database file with 'PRAGMA journal\_mode;' and saw it was 'delete'. Realized the locking model was the bottleneck. Modified the application bootstrap code to execute 'db.pragma\('journal\_mode = WAL'\);' immediately after opening the database. Also set 'synchronous = NORMAL' for performance \(safe with WAL\). Re-tested with multiple windows performing heavy reads and writes concurrently; 'database is locked' errors disappeared completely, and reads no longer blocked on writes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T10:13:23.115993+00:00— report_created — created