2014-12-12 5 views
1

Процесс обновления моего приложения захватывает данные из трех отдельных источников (например, Twitter, Facebook и Google). Мы обновляем каждый в отдельном потоке по соображениям производительности и хотим, чтобы каждый из них имел свою собственную транзакцию SQLite, так как мы можем обрабатывать ~ 500 элементов одновременно, что может занять несколько секунд.Отдельные транзакции SQLite в нескольких потоках

Есть ли способ начать новую транзакцию в потоке, который не «вмешивается» в взаимодействие с другими потоками базы данных?

TLDR: Есть ли у вас несколько транзакций SQLite для разных потоков?


Update: Например, рассмотрим следующий код:

@implementation Update 

- (void)prepareUpdate { 
    [self update:@"Twitter"]; 
    [self update:@"Facebook"]; 
    [self update:@"Google"]; 
} 

- (void)update:(NSString *)platform { 
    dispatch_queue_t newThread = dispatch_queue_create("newThread", NULL); 
    dispatch_async(newThread, ^{ 

     NSDictionary * data = [Platform getData:platform]; 

     [_db beginTransaction]; 
      for (id item in data) { 
       [Platform update:platform withData:item]; 
      } 
     [_db endTransaction]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      NSLog(@"Update complete!"); 

     }); 
    }); 
} 

@end 

, который будет генерировать следующее сообщение об ошибке:

Error whilst preparing query: cannot start a transaction within a transaction 
+0

Возможно, я использовал бы функцию '@ syncrhonized' для доступа к базе данных и отправки всех транзакций через один и тот же объект. –

+0

. Я не хочу, чтобы централизованная точка запроса выполнялась, поскольку пользователь все равно должен использовать приложение/database, в то время как обновления выполняются в фоновом режиме. – cjhill

ответ

0

Как простой вопрос был задан
Replay: Да, вы можете иметь несколько транзакций SQLite через разные потоки.
Reference enter image description here


Больше ссылка
Is SQLite threadsafe?
SQLite является поточно. Мы делаем эту уступку, поскольку многие пользователи предпочитают игнорировать рекомендации, приведенные в предыдущем абзаце. Но для того, чтобы быть потокобезопасным, SQLite должен быть скомпилирован с использованием макроса препроцессора SQLITE_THREADSAFE, установленного в 1. Оба файла с предварительно скомпилированными исполняемыми файлами Windows и Linux в дистрибутиве скомпилированы таким образом. Если вы не уверены в том, что библиотека SQLite, с которой вы связываете, скомпилирована как потокобезопасная, вы можете вызвать интерфейс sqlite3_threadsafe(), чтобы узнать.

SQLite является потокобезопасным, поскольку он использует мьютексы для сериализации доступа к общим структурам данных. Тем не менее, работа по приобретению и выпуску этих мьютексов немного замедлит SQLite. Следовательно, если вам не нужно, чтобы SQLite был потокобезопасным, вы должны отключить мьютексы для максимальной производительности. Дополнительную информацию см. В документации по режиму потока.

В Unix вы не должны переносить открытую базу данных SQLite через системный вызов fork() в дочерний процесс.
enter image description here
Reference

+0

Привет, @Jageen, я уже вызываю 'sqlite3_config (SQLITE_CONFIG_SERIALIZED);' когда я создаю соединение с базой данных и обновил свой первоначальный пост с помощью фрагмента того, как я открываю новый поток, запуская новую транзакцию, которая ведет к ошибке erorr 'Ошибка при подготовке запроса: не удается запустить транзакцию в транзакции'. – cjhill

+0

Я думал, что вы просто хотите, чтобы это было возможно или нет, позвольте мне проверить с новым обновлением :) – Jageen

+0

Это не отвечает на вопрос, касающийся нескольких транзакций. –

1

SQLite имеет одну транзакцию на соединение, поэтому, чтобы получить несколько транзакций, вам необходимо иметь несколько соединений (то есть, объекты базы данных).

Однако это невозможно для multiple transactions to write to the database at the same time.

+0

Спасибо, думаю, мне нужно будет открыть еще несколько соединений. – cjhill

+0

Хм. Я попытался создать два подключения к одной и той же базе данных ('sqlite3_open ([dbPath UTF8String], &db1);' и 'sqlite3_open ([dbPath UTF8String], &db2);'), но когда я пытаюсь выполнить запрос с ними, я получаю множество или ошибки, такие как 'no such table: xyz',' database locked 'и 'unknown error'. В принципе, кажется, что открытие двух соединений с разумной таблицей очень не понравилось. Ps Глядя на их указатели, они указывают на два в разных местах памяти. – cjhill

+0

Затем в вашем приложении есть некоторые ошибки. –

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