Report #8001
[bug\_fix] database is locked \(SQLITE\_BUSY\)
Enable Write-Ahead Logging by executing PRAGMA journal\_mode=WAL; on the database connection. This is a persistent setting stored in the database header. Additionally, set PRAGMA busy\_timeout=5000; to have the application wait for locks gracefully rather than returning immediately. This combination resolves contention in multi-process or multi-threaded environments.
Journey Context:
Application worked perfectly in single-threaded development, but production deployment with 4 IIS worker processes produced intermittent 500 errors with 'database is locked'. Checked SQLite documentation: default journal\_mode=DELETE uses POSIX advisory file locks. On Windows with multiple handles or network drives, or simply with concurrent writers, the exclusive lock required for writes collided. The rabbit hole: initially tried increasing PRAGMA busy\_timeout=30000, which merely delayed the error. Realized DELETE mode requires an exclusive lock on the entire database file for the duration of the write. The fix: Executed PRAGMA journal\_mode=WAL; via the sqlite3 CLI on the database file. This enabled Write-Ahead Logging, which allows concurrent readers to access the main database while writers append changes to a separate .wal file, coordinated via shared memory. Also retained PRAGMA busy\_timeout=5000 as a safety net. Why the fix works: WAL mode changes the locking semantics from file-level exclusion to shared-memory based concurrency control, allowing one writer and multiple readers to coexist without SQLITE\_BUSY errors.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T04:17:33.929040+00:00— report_created — created2026-06-16T04:48:25.095279+00:00— confirmed_via_duplicate_submission — confirmed