SQLite много доступ процесса

Мы используем SQLite во много процессы и многопоточное приложение. Файлы базы данных SQLite шифруются с помощью встроенного шифрования SQLite. FAQ указывает, что SQLite должен смочь управлять много доступами процесса с помощью механизма блокировок. Мы испытываем странную проблему: То, когда много потоков получают доступ к тому же файлу базы данных, когда-то ограничивает нарушения, происходят, более конкретно - поле с уникальным ограничивает, получает дублирующиеся значения после того, как вызов "вставляет или заменяет" оператор. Это происходит довольно часто теперь, что мы используем шифрование. Прежде чем мы начали использовать шифрование SQLite, мы не заметили такого поведения. Есть ли какие-либо определенные известные проблемы с этим?

7
задан Nicolas 5 May 2010 в 17:57
поделиться

3 ответа

Убедитесь, что вы не разделяете соединения между потоками - каждый поток должен создавать собственное соединение. И убедитесь, что вы завершаете свои запросы транзакциями.

Я использую оболочку System.Data.Sqlite с открытым исходным кодом ( http://sqlite.phxsoftware.com/ ) ADO.Net, которая является потокобезопасной, если вы не делитесь соединения по потокам. Он также легко шифрует базу данных, как описано здесь: http://sqlite.phxsoftware.com/forums/t/130.aspx (просто установите свойство пароля). Поищите на его форуме информацию о том, как он конкретно использует Microsoft Crypto API для шифрования, а также подробную информацию о безопасности потоков.

1
ответ дан 6 December 2019 в 21:11
поделиться

Хотя SQLite является "потокобезопасным", вы по-прежнему не может одновременно изменять базу данных:

Затем каждый поток переходит к вставке записей, скажем, 1000. Проблема , с которой вы столкнетесь, заключается в следующем : один поток получит контроль над базой данных, установив блокировку файла. Это нормально, но остальные потоков будут продолжать отказываться для каждой попытки INSERT, пока активна блокировка . ( ссылка )

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

Если вы хотите избежать проблемы с ошибкой при блокировке, вы можете проверить флаг SQLITE_BUSY:

Проверить SQLITE_BUSY, чего я изначально не делал. Вот некоторый псевдокод для иллюстрации решения:

  while (continueTrying) {
    retval = sqlite_exec(db, sqlQuery, callback, 0, &msg);
    switch (retval) {
      case SQLITE_BUSY:
        Log("[%s] SQLITE_BUSY: sleeping fow a while...", threadName);
        sleep a bit... (use something like sleep(), for example)
        break;
      case SQLITE_OK:
        continueTrying = NO; // We're done
        break;
      default:
        Log("[%s] Can't execute \"%s\": %s\n", threadName, sqlQuery, msg);
        continueTrying = NO;
        break;
    }
  }

  return retval;

та же ссылка

Моя ставка заключается в том, что ваше нарушение ограничений не имеет ничего общего с многопоточностью, поэтому не могли бы вы опубликовать фактическое нарушение ограничения, которое вы получение (или пример, соответствующий www.sscce.org ).

9
ответ дан 6 December 2019 в 21:11
поделиться

Спасибо за все ваши комментарии!

(следует отметить, что мы используем библиотеку System.Data.SQLite .Net)

Тем временем мы провели еще несколько тестов, и вот результаты

========== =====

Мы создали тестер, который выполняет следующие действия: - создает таблицу с несколькими полями. Одно из полей - nvarchar (255) - имеет уникальный индекс: «создать уникальный индекс IX_MyKey в таблице (MyKey)» - запустить несколько идентичных процессов (25) одновременно - у каждого процесса есть Ключ (строка, представляющая число 1-25) - у каждого процесса есть единственный (основной) поток, выполняющий следующие действия в цикле в течение 30 секунд:

чтение записи, где MyKey = @ MyKey (ключ процесс) получить значение числового поля записать "значение + 1" в то же поле той же записи "вставить или заменить ... где MyKey = @ MyKey"

===============

  • Когда мы делаем все выше, используя System.Data.Библиотека SQLite без шифрования - все работает, как ожидалось (включая блокировки, которые замедляют доступ к базе данных при увеличении количества процессов)

  • Когда мы используем шифрование (путем установки пароля к базе данных), уникальное ограничение индекса равно "broken" - появляются записи с таким же значением MyKey

===============

Таким образом, похоже, проблема каким-то образом связана с шифрованием ...

{ {1}}
2
ответ дан 6 December 2019 в 21:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: