El modo WAL de SQLite puede bloquear a lectores de corta duración

Fuentes: SQLite WAL Mode Can Lock Short-Lived Readers

El modo WAL (Write-Ahead Logging) de SQLite se presenta a menudo como la solución al clásico error "database is locked", junto con un tiempo de espera de ocupado y transacciones BEGIN IMMEDIATE para escrituras. Sin embargo, este artículo técnico explica por qué esa combinación puede fallar en una carga de trabajo atípica: aplicaciones que escriben muy rara vez (menos de una vez al mes) pero leen decenas o cientos de veces por segundo desde procesos independientes sin pool de conexiones, abriendo la base en modo solo lectura (SQLITE_OPEN_READONLY), ejecutando un SELECT y cerrando.

El problema reside en el ciclo de vida de las conexiones en WAL: la coordinación se realiza mediante el archivo -shm, y abrir o cerrar una base WAL puede requerir brevemente bloqueos exclusivos. Un nuevo lector que llegue en esa ventana recibe SQLITE_BUSY, aunque no se esté escribiendo dato alguno. La biblioteca C de SQLite tiene por defecto un timeout de conexión de 0, lo que hace visibles errores que, con un busy_timeout mayor, pasarían desapercibidos. El autor lo verificó observando cómo los archivos -shm y -wal se actualizaban constantemente a pesar de no haber escrituras reales en días.

La solución adoptada fue cambiar las bases al modo DELETE, con lo que el error desapareció. El artículo incluye un script reproducible en Python que lanza 64 procesos concurrentes en tres escenarios (WAL sin busy timeout, WAL con 1 s de busy timeout y DELETE sin busy timeout), demostrando entre 1 y 10 fallos en el primer caso y 0 en los otros dos sobre 6.400 operaciones.