LINUX.ORG.RU

Ошибка «database is locked» не пропадает даже когда выхожу из второго приложения.

 ,


0

1

В моём приложении создаю коннекты и 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. Что там вообще происходит?

★★★★★

Последнее исправление: dimgel (всего исправлений: 9)

Похоже пофиксил. Нашёл у себя несколько запросов на чтение в auto-commit режиме, где не вызываю reset() после step(). В результате implicit-транзации висят вечно (т.к. prepared statements закешированы) и держат read locks. Каким конкретно образом это приводит к наблюдаемым фейрверкам, лень думать.

Тут:

An implicit transaction (a transaction that is started automatically, not a transaction started by BEGIN) is committed automatically when the last active statement finishes. A statement finishes when its last cursor closes, which is guaranteed to happen when the prepared statement is reset or finalized.

dimgel ★★★★★
() автор топика