В моём приложении создаю коннекты и prepared statements по запросу, и в описываемом сценарии считаем что кеширую их вечно. Все обновления базы – внутри транзакций.
Во время работы приложения в консоли запускаю sqlite3 mydb
и там что-нибудь модифицирую (create table aaa(id int);
, drop table aaa;
) в auto-commit режиме. После чего моё приложение естественно начинает ругаться «database is locked» (SQLITE_BUSY). (А может и не естественно, если консоль в auto-commit отпускает лок после каждой команды.)
Проблема в том, что даже после того, как я выйду из sqlite3 в консоли, моё приложение продолжает ругаться.
Причём там непонятная хрень какая-то творится. Prepared statements, которые были созданы ПОСЛЕ того, как я вышел из консоли, работают. Решил убедиться, запустил консоль, сделал create/drop table, а потом, НЕ выходя из консоли, запустил приложение – всё работает. Но стоит ещё раз повторить в этой же консоли create/drop table – начинает ругаться.
SQLite 3.43.2, база на локальной ФС, режим журналирования WAL, по коннекту на поток, sqlite3_open_v2(...SQLITE_OPEN_NOMUTEX...)
, pragma locking_mode = normal
.
Куда копать, кроме постгреса и кладбища? Ну и кроме очевидного, но чересчур грубого pragma locking_mode = exclusive
. Что там вообще происходит?