Report #85067
[bug\_fix] SQLite "database is locked" \(SQLITE\_BUSY\)
Set \`PRAGMA busy\_timeout = 5000\` \(milliseconds\) on each connection. Root cause: SQLite uses file-level POSIX advisory locks; with default busy\_timeout=0, a second writer immediately receives SQLITE\_BUSY if the file is locked, rather than waiting for the first writer to commit.
Journey Context:
Developer runs a Python Flask app with gunicorn workers using SQLite in WAL mode. During concurrent form submissions, one worker logs 'database is locked'. Investigation shows both workers do \`BEGIN EXCLUSIVE\` then \`INSERT\`. The first acquires the exclusive lock; the second attempts to acquire it, gets BUSY immediately, and raises. Developer initially thinks WAL mode eliminates locking, but WAL only separates readers from writers—writers still serialize. The fix works because \`busy\_timeout\` causes SQLite to sleep and retry the lock acquisition for the specified duration. When the first writer commits within 5 seconds, the second writer acquires the lock and proceeds, converting the hard error into brief latency rather than a crash.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T01:22:14.779688+00:00— report_created — created