Я знаю, что сообщение SQLite error (5): database is locked
означает, что существует некоторая одновременная запись в базу данных.Но здесь я пытаюсь поместить все данные (из нескольких потоков) в ConcurrentQueue
и заблокировать код, обрабатывающий эту очередь, чтобы гарантировать, что в очереди работает только один поток, что означает, что в базу данных одновременно записывается только один поток.
Код выглядит примерно так:
public class DataService {
readonly ConcurrentQueue<Item> _cacheQueue = new ConcurrentQueue<Item>();
public void SaveItem(Item item) {
_cacheQueue.Enqueue(item);
_processQueue();
}
void _saveItemCore(Item item){
//logic here to save the item (with write access to the SQLite database)
}
bool _isProcessingQueue;
object _lo = new object();
void _processQueue(){
lock(_lo){
if(_isProcessingQueue) return;
_isProcessingQueue = true;
while(_cacheQueue.Count > 0){
Item e;
if(_cacheQueue.TryDequeue(out e)){
_saveItemCore(e);
}
}
_isProcessingQueue = false;
}
}
}
У меня несколько потоков (каждая соответствует Task.Run
).Все потоки вызывают метод SaveItem
одновременно.
Но, как вы видите, мой код не работает, я все равно вижу сообщение SQLite error (5): database is locked
.Что может быть здесь не так?
ПРИМЕЧАНИЕ: мои потоки также выполняют чтение в базу данных, поэтому, если в данный момент запись в БД выполняется одним потоком, он заблокирует чтение другим потоком?Если это так, то это может объяснить мою проблему.
ОБНОВЛЕНИЕ : Я также попытался включить режим журнала WAL, изменив строку подключения следующим образом:
data source=app.db;PRAGMA journal_mode=WAL;
но я все еще вижу сообщение SQLite error (5): database is locked
.Я не уверен, что все в порядке, независимо от того, было ли чтение успешным или нет.