Подтвердить что ты не робот

Android Lollipop 5.0.1 SQLiteLog POSIX Ошибка 11 Ошибка SQLite: 3850

У меня возникла проблема при обновлении приложения для поддержки Android Lollipop. Приложение реализует SyncAdapter, который записывает данные через db через поставщика контента. В то же время может случиться так, что пользователь просматривает внешний интерфейс приложения, где загрузчики считывают одни и те же данные из базы данных. Погрузчики также прослушивают изменения данных.

Теперь, если я запускаю программу на устройстве pre-Lollipop, все работает без вывода ошибок.

Вместо Lollipop я получаю следующее сообщение logcat:

11:20:59.344  22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850

Теперь, из документов SQLite:

(3850) SQLITE_IOERR_LOCK

Код ошибки SQLITE_IOERR_LOCK - это расширенный код ошибки для SQLITE_IOERR указывает на ошибку ввода-вывода в блокировке консультативного файла логика. Обычно ошибка SQLITE_IOERR_LOCK указывает на проблему получая блокировку PENDING. Однако он также может указывать на разное ошибки блокировки на некоторых специализированных VFS, используемых на компьютерах Mac. Кажется, что все работает правильно на высоком уровне (это как чтение и записи выполняются)

и

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

Я знаю, что версия SQLite была обновлена ​​несколькими основными выпусками в Lollipop, поэтому я склонен думать, что ошибка связана с каким-то новым поведением SQLite, которое я не могу изолировать.

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

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

Есть ли способ исправить это, возможно, без распространения конкретной версии SQLite для приложения? Есть ли опция manifest/SQLite, чтобы избежать ошибки?

Заранее спасибо

4b9b3361

Ответ 1

Writer блокирует базу данных для чтения и записи. Это означает, что он должен ждать, пока все читатели закончат и освободят блокировки, чтобы получить блокировку.

После того, как писатель запросил блокировку, новые блокировки считывателя должны дождаться, когда писатель сначала получит блокировку, а затем освободит ее.

Это может быть для вас решением: Режим WAL

Активация и настройка режима WAL:

Соединение с базой данных SQLite по умолчанию имеет значение journal_mode = DELETE. Чтобы преобразовать в режим WAL, используйте следующую прагму:

PRAGMA journal_mode=WAL;

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

Минимальная версия SQLite, необходимая для WAL, - 3.7.0 (2010-07-21). Lollipop 5.0 использует SQLite 3.8.4.3, поэтому WAL должен быть доступен для вас.

Но WAL не существует в версии для Android менее 3.0, хотя из этого есть некоторые исключения. Взгляните на версию SQLite, используемую в Android?. Если вам не нужно ваше приложение для работы под Android 3.0, вы можете использовать WAL.