2012-01-25 2 views
1

У меня есть представление, в которое я вставляю данные в фоновый поток в базу данных sqlite, поступающую с сервера. Теперь, когда пользователь забирает и переходит к другому представлению, в котором я должен читать содержимое из этой базы данных, но я не могу получить содержимое, поскольку база данных уже открыта в фоновом потоке последнего представления, и она дает ошибку «база данных заблокирована ».Синхронизировать базу данных sqlite в объекте-C

ПРИМЕЧАНИЕ: обе операции находятся в разных таблицах. Я пишу в другой таблице и читаю из другой таблицы.

Поддерживает ли sqlite многопоточность, если да, то как я могу удалить блокировку из базы данных?

ответ

3

SQLite поддерживает многопоточность. Вы можете поделиться своим дескриптором соединения/объектом между потоками, они будут хорошо синхронизировать их доступ.

EDIT: передать объект sqlite3 (тот, который sqlite3_open() возвращает как второй параметр) в поток вместо повторного открытия базы данных в потоке. Что-то вроде этого:

sqlite3 *MyDatabase; //Initialized somewhere 
NSArray *DataForThread = [NSArray arrayWithObjects: 
    request, 
    [NSValue valueWithPointer: MyDatabase], 
    nil]; 

[self performSelectorInBackground:@selector(processResponseInBackground:)  withObject:DataForThread]; 

Внутри нити, восстановить объект SQLite3 как это:

sqlite3 *MyDatabase = [[ThreadData objectAtIndex:1] pointerValue]; 
+0

@Seve Было бы неплохо, если бы вы предоставили некоторый фрагмент кода. Спасибо –

+0

Вы первый. Как открыть базу данных и запустить фоновый поток? –

+0

В первом представлении, когда данные поступают с сервера, вставьте данные в фоновом режиме, используя «[self performSelectorInBackground: @selector (processResponseInBackground :) withObject: request]; и когда я перемещаюсь из этого представления, он все еще использует базу данных, а база данных заблокирована для другого представления. –

3

SQLite не поддерживает многопоточность, но не поддерживает одновременный доступ к базе данных из нескольких потоков.

Если вы обращаетесь к SQLite из нескольких потоков в Objective-C, вы должны использовать какой-то механизм блокировки для координации доступа к дескриптору базы данных. Одним из вариантов является ключевое слово @synchronized.

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

Один из вариантов состоит в том, чтобы поместить две таблицы в две разные базы данных и создать для них два разных соединения.

Дальнейшее чтение о характере использования SQLite в многопоточной среде:

http://www.sqlite.org/threadsafe.html

http://www.sqlite.org/faq.html#q6

1

Sqlite поддерживает многопоточность в смысле «писать так быстро, чтобы избежать проблем параллелизма ». Реальность такова, что не должно быть проблем с блокировкой в ​​случае только для чтения запросов, но если вы тоже хотите написать ... вы можете встретить ошибку SQLITE_BUSY. Вы можете избежать его несколькими способами:

  • либо делать все запросы в одном потоке (но если бы вы могли это сделать ...нет вопросов о stackoverflow :-))

  • или, как упомянуто выше, разбивать таблицы базы данных на два или более файла (группируя таблицы с меньшими доступом к параллелизму или только с доступом только для чтения) и создавая для каждого файла другое соединение db

  • или, как упоминалось выше, с использованием подхода синхронизации нити для каждого метода (или блока кода), который выполняет запрос (чтобы убедиться, что db будет заблокирован при запуске использования транзакции «НАЧАТЬ НЕМЕДЛЕННЫЙ ПЕРЕВОД»)

  • или, обработайте sqlite: занятую ошибку с помощью двух обратных вызовов, предоставленных c api, «sqlite_busy_handler» и «sqlite_bus» y_timeout»

  • или после получения ошибок блокировки в ожидании в течение 1-2 секунд и повторите попытку (лучше приближаться к точке выше я думаю)

Я предпочитаю, чтобы уменьшить параллелизм расщепление дБ, а затем при необходимости синхронизации потоков доступ к коду запроса. Это просто ваш выбор ...

Смежные вопросы