Одновременное чтение и запись SQLite

Я прочитал много тем, но не могу понять ответ на вопрос: возможно ли читать и писать одновременно?

У меня есть фоновый поток, который обновляет некоторые данные, а пользовательский интерфейс требует небольшого объема данных, хранящихся в БД. Таким образом, в пользовательском интерфейсе выполняется операция SELECT. Но он блокируется при обновлении. В результате пользовательский интерфейс зависает в течение нескольких секунд.

Кто-нибудь имеет успех в чтении из БД при написании?


Его можно читать и писать в БД на iPhone. Есть ли причина такой разницы в синхронной реализации оболочки для собственных функций sqlite?

Solutions Collecting From Web of "Одновременное чтение и запись SQLite"

На Android 3.0 и выше SQLiteDatabases поддерживает режим WAL (запись на запись):

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

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

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging ()

Чтобы начать транзакцию в режиме WAL, используйте beginTransactionNonExclusive () вместо beginTransaction (). Хотя beginTransaction () запускает транзакцию в режиме EXCLUSIVE, beginTransactionNonExclusive () запускает одно в режиме IMMEDIATE

  • В режиме EXCLUSIVE используются эксклюзивные блокировки ( http://www.sqlite.org/lockingv3.html#excl_lock ), что означает, что никакое другое соединение с базой данных, кроме подключений read_uncommitted, сможет читать базу данных, и никакое другое соединение без исключения не сможет написать До завершения транзакции
  • Режим IMMEDIATE использует зарезервированные блокировки ( http://www.sqlite.org/lockingv3.html#reserved_lock ), что означает, что никакое другое соединение с базой данных не сможет записывать в базу данных или выполнять НАЧАЛЬНУЮ НЕМЕДЛЕННОСТЬ или НАЧАТЬ ЭКСКЛЮЗИВ, другие процессы могут продолжать читать Из базы данных.

В более простых словах: call beginTransactionNonExclusive () для режима IMMEDIATE, и мы можем читать, пока записывается другой поток (состояние до начала транзакции записи, потому что мы не будем использовать read_uncommitted connections -> http://en.wikipedia.org/wiki/ Isolation_% 28database_systems% 29 # Dirty_reads ).

Вы не можете читать и писать одновременно. SQLite – это безсерверная файловая база данных.

Из SQLite FAQ:

«Когда какой-либо процесс хочет писать, он должен блокировать весь файл базы данных на время его обновления, но обычно это занимает всего несколько миллисекунд. Другие процессы просто ждут завершения записи, а затем продолжат свою деятельность. Двигатели обычно позволяют только одному процессу напрямую подключаться к базе данных ».

Начиная с API 11 Android поддерживает режим WAL. Он сохраняет исходные данные незатронутыми во время транзакции, поэтому другие потоки могут читать, когда транзакция выполняется. Вы можете проверить мою статью для получения более подробной информации о режиме WAL:

http://www.skoumal.net/en/parallel-read-and-write-in-sqlite/

Вы также должны избегать запуска запросов к базе данных в потоке пользовательского интерфейса. Он всегда может стать вялым и блокировать ваш пользовательский интерфейс.

Невозможно читать и писать одновременно. Однако, если у вас правильно настроены классы базы данных SQLite (один экземпляр ваших классов DB и вспомогательных), разные потоки должны иметь возможность синхронно захватывать соединение с БД, чтобы не было заметного отставания.

Это также звучит так, будто вы пытаетесь сделать бэкэнд-работу (напишите в db) с помощью потока пользовательского интерфейса. Вы не должны этого делать. Создайте AsyncTask, чтобы обработать это, вместо того, чтобы обработать его поток пользовательского интерфейса.

Обратитесь к документации SQLiteOpenHelper . Вот предыдущая статья, которая говорит об этом также: Каковы лучшие практики для SQLite на Android?