Как предотвратить блокировки базы данных SQLite?


10

Из SQLite FAQ я знаю, что:

Несколько процессов могут одновременно открывать одну и ту же базу данных. Несколько процессов могут выполнять SELECTодновременно. Однако только один процесс может вносить изменения в базу данных в любой момент времени.

Итак, насколько я понимаю , я могу: 1) Чтение БД из нескольких потоков ( SELECT) 2) Чтение дб из нескольких потоков ( SELECT) и запись из одной нити ( CREATE, INSERT, DELETE)

Но я читал о журналировании записи вперед, которое обеспечивает больше параллелизма, поскольку читатели не блокируют писателей, а писатель не блокирует читателей . Чтение и запись могут происходить одновременно.

Наконец, я совсем запутался, когда нашел его , когда указал:

Вот другие причины для получения ошибки SQLITE_LOCKED:

  • Попытка CREATEили DROPтаблицы или индекса, пока SELECTоператор еще не завершен.
  • Попытка записи в таблицу, пока SELECTактивна эта таблица.
  • Попытка сделать два SELECTна одной и той же таблице одновременно в многопоточном приложении, если sqlite не настроен на это.
  • fcntl (3, сбой вызова F_SETLK для файла DB. Это может быть вызвано, например, проблемой блокировки NFS. Одним из решений этой проблемы является удаление базы данных из базы данных и ее копирование обратно, чтобы у нее было новое значение Inode

Итак, я хотел бы уточнить для себя, стоит ли избегать блокировки? Могу ли я читать и писать одновременно из двух разных тем? Спасибо.

Ответы:


8

На той странице, на которую вы ссылались, помимо того, что она довольно старая, говорится о доступах из того же процесса через одно и то же соединение с базой данных (или через множественные соединения в режиме общего кэша , который вы не должны использовать).

Когда не в режиме WAL, несколько соединений могут читать из одной и той же базы данных, но транзакция записи является исключительной, то есть никакие другие устройства чтения или записи не допускаются.

В режиме WAL писатель и читатели не блокируют друг друга, но разрешен только один писатель.


1
Что не так с режимом общего кэша? Мне удалось получить несколько потоков Python в одном и том же процессе, чтобы записать в него таблицу с помощью задания параллельного цикла joblb . У меня были проблемы с блокировкой до набора, isolation_level=Noneхотя. Без режима общего кэша, как я могу делиться экземплярами между потоками?
Джастин Даринг

1
В документации описаны недостатки. Это особенно опасно, если вы не знаете, как избежать тупиков.
кл.

Приходит очень поздно на вечеринку, но эта ссылка полезна. manski.net/2012/10/sqlite-performance
инфоцид
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.