Трудность запуска одновременных вставок в базе данных SQLite в C # - PullRequest
4 голосов
/ 19 мая 2009

Я использую несколько потоков, каждый из которых пытается выполнить INSERTS для одной базы данных SQLite. Каждый поток создает свое собственное соединение с БД. Каждый из них создает команду, открывает транзакцию, выполняет некоторые ВСТАВКИ, а затем закрывает транзакцию. Похоже, что второй поток, пытающийся что-либо предпринять, получает следующее исключение SQLiteException: файл базы данных заблокирован. Я попытался удалить INSERTS из транзакции, а также сузить область действия INSERTS, содержащейся в каждом коммите, без реального эффекта; последующий доступ к файлу базы данных вызывает то же исключение.

Есть мысли? Я в тупике, и я не уверен, где искать дальше ...

Ответы [ 3 ]

5 голосов
/ 19 мая 2009

Обновите код вставки, чтобы в случае обнаружения исключения, указывающего на блокировку базы данных, он немного подождал и повторил попытку. Увеличивайте время ожидания случайными приращениями каждый раз (алгоритм «случайного отката»). Это должно позволить потокам захватывать глобальную блокировку записи. Производительность будет низкой, но код должен работать без существенных изменений.

Однако SQLite не подходит для высококонкурентной модификации. У вас есть два постоянных решения:

  • Перейти к «реальной» базе данных, такой как PostgreSQL или MySQL
  • Сериализуйте все ваши модификации базы данных через один поток, чтобы избежать модификаций SQLite.
1 голос
/ 19 мая 2009

Две вещи для проверки:

1) Подтверждено, что ваша версия SQLite была скомпилирована с поддержкой THREAD

2) Подтвердите, что вы не открываете базу данных EXCLUSIVE

0 голосов
/ 13 мая 2011

Я делал это не в C #, а в Android, но обошел эту ошибку «база данных заблокирована», оставив базу данных sqlite всегда открытой в пределах класса-оболочки, которому она принадлежит, в течение всего времени существования класса-оболочки , Каждая вставка, выполняемая в этом классе, может быть в своем собственном потоке (потому что, в зависимости от вашей ситуации с хранением данных, SD-карты в зависимости от памяти устройства и т. Д., Запись в БД может занять много времени), и я даже попытался ее удушить, делая около дюжина потоков вставки одновременно, и каждый из них был обработан очень хорошо, потому что метод вставки не должен беспокоиться об открытии / закрытии БД.

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

...