3

В моем приложении я вызываю некоторые веб-службы для обновления базы данных. Каждый вызов webservice выполняется в определенном потоке, в результате чего несколько потоков обновляют объект базы данных «за раз».Операции SQLite SQLite и несколько потоков

В каждом потоке, я использую транзакции так:

Thread 1 (webservice 1) 
beginTransaction() 
insert a row in the table 1 
update a row in the table 1 
endTransaction() 

Thread 2 (webservice 2) 
beginTransaction() 
update a row in the table 2 
update a row in the table 2 
endTransaction() 

Но я борюсь с одним вопросом я не могу ответить себе после того, как его прибегая к помощи; Как транзакции обрабатываются в разных потоках, отличаются ли они друг от друга? Другими словами, использует ли БД отдельный «стек операторов» или общий?

Из моих показаний, я понимаю сделки в одном стеке, то есть совершали сделки в потоке 1 может совершать обновления на таблице 2. Например, DB стек заявление, как я думаю, что это может произойти:

beginTransaction() //Thread 1 begins a transaction 
insert a row in the table 1 
update a row in the table 1 
beginTransaction() //Thread 2 begins a transaction 
update a row in the table 2 
update a row in the table 2 
endTransaction() //Thread 2 ends a transaction 
endTransaction() //Thread 1 ends a transaction 

Если это правда, как я могу сделать свои транзакции действительно эксклюзивами? У меня есть BEGIN EXCLUSIVE TRANSACTION и обрабатывать ошибку SQLITE_BUSY всюду или что-то еще проще?

+0

Одна идея состоит в том, чтобы использовать Singleton шаблон в вашем DBHandler или класса DBadapter. И синхронизировать инструкции вставки – drulabs

ответ

1

Я рекомендую читать далее, чтобы понять, как работают режимы транзакций. From SQLite руководство пользователя:

Сделки можно отложить, незамедлительно или бесплатно. Поведение транзакции по умолчанию отложено. Отложенное означает, что в базе данных не фиксируются блокировки до момента обращения к базе данных. Таким образом, с отложенной транзакцией оператор BEGIN сам по себе ничего не делает для файловой системы. Замки не приобретаются до первой операции чтения или записи. Первая операция чтения с базой данных создает блокировку SHARED, и первая операция записи создает блокировку RESERVED. Поскольку приобретение блокировок отложено до тех пор, пока они не понадобятся, возможно, что другой поток или процесс могут создать отдельную транзакцию и записать в базу данных после того, как BEGIN на текущем потоке выполнит. Если транзакция немедленна, блокировки RESERVED будут получены во всех базах данных, как только будет выполнена команда BEGIN, не дожидаясь использования базы данных. После BEGIN IMMEDIATE никакое другое соединение с базой данных не сможет записать в базу данных или выполнить BEGIN IMMEDIATE или BEGIN EXCLUSIVE. Однако другие процессы могут продолжать считывать из базы данных. Исключительная транзакция вызывает блокировку EXCLUSIVE для всех баз данных. После BEGIN EXCLUSIVE никакое другое соединение с базой данных, кроме подключений read_uncommitted, не сможет прочитать базу данных, и никакое другое соединение без исключения не сможет записать базу данных до завершения транзакции.

https://www.sqlite.org/lang_transaction.html

Андроида API предоставляет способ борьбы с этими режимами транзакций, поэтому выбор, который лучше подходит для вашего приложения.

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

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