У меня есть приложение (Android 2.2 Google API уровня 8), в котором несколько действий извлекают данные от поставщика контента (только для базы данных SELECT доступ). В нем также есть служба с центральной блокирующей очередью задач, которая принимает любые задачи записи в базу данных; Действия могут запускать запрос на обслуживание (как намерение), который помещает задачу в очередь блокировки для последовательного извлечения одним потоком и выполнения. База данных составляет около 4 МБ.
Существует единственный помощник базы данных, который служба использует для вызова методов взаимодействия с базой данных, включая запись в нее; все записи SQL выполняются в помощнике базы данных.
Во время выполнения задач я постоянно получаю одну или две ошибки «база данных заблокирована» при попытке записи в базу данных, вызванных выполнением задачи «начать транзакцию».
Пытаясь отследить источник блокировки, я обнаружил, что использование dbhelper.inTransaction (), dbhelper.isLockedByThisThread (), dbhelper.isLockedByOtherThread () не помогает, поскольку они не указывают на неожиданную блокировку базы данных.
Я обнаружил, что сработало для раннего обнаружения блокировки, так это создание метода с beginTransaction () и setTransactionSuccessful без какого-либо фактического кода записи SQL в блоке try catch, который регистрировал проблему - всегда запускается beginTransaction ().
Я поместил эту ловушку блокировки базы данных по обе стороны от каждого из методов задачи очереди блокировки в ожидании / надежде, что я найду единственного виновника, который оставил базу данных в заблокированном состоянии после завершения. Я мог бы не найти последовательного виновника. После детализации от начала вызова задачи до записи в базу данных я обнаружил, что блокировка базы данных может произойти, казалось бы, неожиданно, не будучи заблокированной ранее запущенной задачей (все эти задачи выполняются последовательно в одном и том же единственном потоке. ).
После изучения опыта ряда других людей с проблемами блокировки базы данных я попытался закрыть соединение с базой данных сразу после завершения транзакции для всех задач, но это не помогло, если что-то, казалось, приводило к большему количеству блокировок базы данных.Пробовал добавлять сон между выполнением каждой задачи; не проводился исчерпывающим тестированием, но в целом обнаружил, что задержка в 3 секунды или более, кажется, останавливает появление блокировок базы данных. Пробовал отключать задачи, запущенные диспетчером тревог, - без разницы.
У меня сложилось впечатление, что какая-то внешняя по отношению к моему приложению задача обслуживания периодически блокируется и блокирует базу данных - возможно, с задержкой записи журналов. Очевидно, я не очень заинтересован в установке задержки обработки задачи, поэтому я рассматриваю возможность создания очереди задач повтора блокировки базы данных для повторной попытки записи в базу данных по мере необходимости; я предпочитаю разрешить, но у меня заканчиваются идеи.
Кто-нибудь может придумать какой-нибудь принцип или ошибку, которую я пропустил?
Является ли в действительности нормальным в Android и более крупных базах данных SQLite случайные блокировки базы данных?
Спасибо