Мы используем SQLite в многопроцессорном и многопоточном приложении. Файлы базы данных SQLite шифруются с использованием встроенного SQLite-шифрования. FAQ утверждает, что SQLite должен иметь возможность управлять несколькими процессами с помощью механизма блокировок. У нас возникает странная проблема: Когда многие потоки обращаются к одному и тому же файлу базы данных, иногда происходят нарушения ограничений, а более конкретно - поле с уникальным ограничением получает повторяющиеся значения после вызова инструкции «вставить или заменить». Часто случается, что мы используем шифрование. Прежде чем мы начали использовать SQLite-шифрование, мы не заметили такого поведения. Существуют ли какие-либо конкретные проблемы с этим?SQLite multi process access
ответ
Хотя SQLite является «потокобезопасной» по-прежнему не может одновременно изменять базу данных:
Затем каждая нить переходит вставить количество записей, скажем 1000. проблема вы столкнетесь это следующее: один поток получит управление над базой данных, установив замок на файл. Это нормально, но остальные из нитей будут продолжать сбой для каждой попытки INSERT, если активна блокировка . (reference)
только один поток разрешается изменять базу данных в то время, но вы можете иметь несколько потоков, которые попытка изменения базы данных.
Если вы хотите, чтобы избежать неисправной-то время автоподстройки вопрос вы можете проверить флаг 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).
Убедитесь, что вы не используете соединения по нитям - каждая нить должна создавать свое собственное соединение. И убедитесь, что вы завершаете свои запросы в транзакциях.
Я использую open-source System.Data.Sqlite (http://sqlite.phxsoftware.com/) Обертку ADO.Net, которая является потокобезопасной, если вы не используете общие потоки. Он также легко шифрует базу данных, как описано здесь: http://sqlite.phxsoftware.com/forums/t/130.aspx (просто установите свойство пароля). Найдите на своем форуме, как он специально использует Microsoft Crypto API для шифрования, а также подробную информацию о безопасности потоков.
Спасибо за все ваши комментарии!
(это означает, что мы используем System.Data.SQLite.Чистая библиотека)
В то же время мы сделали еще несколько тестов, и вот результаты
===============
Мы построили тестера делает следующее: - создает таблицу с несколькими полями. Одно из полей - nvarchar (255) - имеет уникальный индекс: «Создайте уникальный индекс IX_MyKey в таблице (MyKey)» - одновременно запускайте множество идентификационных процессов (25) - Каждый процесс имеет ключ (строка, представляющая число 1- 25) - Каждый процесс имеет один (главный) поток, выполнив следующие действия в цикле в течение 30 секунд:
прочитал запись, где MyKey = @ MyKey (ключ процесса) получить значение а числовое поле записать «значение + 1» в одно и то же поле той же записи «вставить или заменить ... где MyKey = @ MyKey»
===============
Когда мы делаем все выше, используя библиотеку System.Data.SQLite без шифрования - все работает, как и ожидалось (в том числе и замков, замедляющих доступ к базе данных, когда количество процессов увеличивается)
когда мы используем шифрование (путем установки пароля к базе данных), индекс уникальным Ограничить является «сломанным» - там появляются записи, имеющих одинаковое значение MyKey
==============
Итак, проблема в том, что проблема связана с шифрованием ...
- 1. vb.net multi process
- 2. multi-process C++ fifo
- 3. epoll multi process
- 4. boost :: asio server multi-process
- 5. Ruby Multi Process Postgress Connections
- 6. Salesforce multi organization access
- 7. Dokku multi-process (container) с проектом Dockerfile
- 8. multi-process in C: значение глобальной переменной
- 9. daemonizing celery process celeryd-multi не найден
- 10. SQLite multi row export
- 11. Android sqlite multi table
- 12. ResultSet sqlite multi multi columns и multi tables
- 13. java multi threads access Hashtable
- 14. MS Access Multi-Join Query
- 15. Android sqlite with multi thread
- 16. SQLite optimizing multi-select insert
- 17. sqlite return subquery multi column
- 18. Sqlite API boolean access
- 19. Google Glass Sqlite Access
- 20. sqlite ios thread access
- 21. Число атрибутов xml-> javascript multi array-> function/process
- 22. Same exe file, multi process и различные аргументы ввода
- 23. Node single file run with multi child process
- 24. Multi-process Class не хранит данные в реальном процессе
- 25. jQuery Multi Window Access and Handlers
- 26. opencv matrix multi channel access and fill
- 27. multi file access to singleton class
- 28. MS Access 2010 Multi column Combobox Autocomplete
- 29. SQLite db access с java
- 30. access sqlite из другого приложения
SQLite заявляет, что вы не можете делиться одним и тем же объектом по потокам. вы уверены, что не делаете этого? – Andrey
@ Andrey: можете ли вы разместить ссылку на это сообщение? Когда я недавно прочитал об этом, SQLite говорит, что он потокобезопасен *, хотя * они считают, что потоки злы, и что вы не должны использовать SQLite в многопоточной программе, если только к нему не обращается только один поток. Но технически, он должен быть потокобезопасным. По крайней мере, это то, что я вспоминаю. – Dave
@Dave: http://www.sqlite.org/cvstrac/wiki?p=MultiThreading ключевая фраза: под «threadsafe» мы подразумеваем, что вы можете использовать разные соединения базы данных SQLite в разных потоках одновременно. – Andrey