Является ли Sqlite Database экземпляр потокобезопасным - PullRequest
31 голосов
/ 13 июля 2011

У меня есть база данных с некоторыми таблицами. Я хочу обновить таблицы, используя несколько потоков. Я буду использовать один и тот же экземпляр SQLiteDatabase во всех потоках.

Пожалуйста, предложите, если этот подход правильный. Безопасна ли база данных Sqlite? Могут ли два разных потока одновременно обновлять одну и ту же таблицу для разных значений.

Ответы [ 4 ]

27 голосов
/ 13 июля 2011

[WRONG:] Нет, по умолчанию он не является потокобезопасным.Вы должны использовать связанные с блокировкой методы SQLiteHelper для обеспечения безопасности потока.

[РЕДАКТИРОВАТЬ]: Класс SQLiteDatabase обеспечивает механизм блокировки по умолчанию (см. Комментарии)и если вы работаете с многопоточностью, вам не нужно менять что-либо для обеспечения безопасности потоков.

Искать «нить» в этом документе: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

И читать дальше:

5 голосов
/ 19 апреля 2015

Android использует механизм блокировки java для сериализации доступа к базе данных SQLite. Таким образом, если у нескольких потоков есть один экземпляр базы данных, он всегда обращается к базе данных сериализованным образом и, конечно, база данных является поточно-безопасной .

Если мы подтвердим, что мы используем базу данных из одного потока, у нас была возможность отключить внутреннюю блокировку базы данных, вызвав setLockingEnable(false), но этот метод получил устаревший с уровня API 16 и больше не используется. если вы увидите реализацию этого метода в SQLiteDatabase классе, вы не найдете там ничего написанного, т.е. пустой метод.

public void setLockingEnabled (boolean lockingEnabled)

Этот метод теперь ничего не делает. Не использовать.

Одна вещь, о которой мы должны позаботиться, это то, что мы должны сделать один экземпляр вашего вспомогательного класса (т.е. сделать его одноэлементным) и совместно использовать один и тот же экземпляр для нескольких потоков и не вызывать close() в базе данных между операциями, в противном случае Вы можете получить следующее исключение:

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

Таким образом, не вызывайте database.close() между доступом к базе данных, база данных самостоятельно выполнит внутреннюю операцию закрытия, когда все операции будут завершены.

2 голосов
/ 13 июля 2011

Вы можете контролировать, является ли ваша база данных поточно-ориентированной или нет setLockingEnabled .

Контролировать, станет ли база данных SQLiteD потокобезопасной, используя блокировки вокруг критических секций.Это довольно дорого, поэтому, если вы знаете, что ваша БД будет использоваться только одним потоком, вам следует установить для этого параметра значение false.Значение по умолчанию - true

Так что я думаю, что это отвечает на ваш вопрос.

Метод setLockingEnabled устарел на уровне API 16

0 голосов
/ 13 июля 2011

Если вы сделаете это ..

setLockingEnabled (boolean lockEnabled) Управляет тем, что SQLiteDatabase сделан поточно-безопасным, используя блокировки вокруг критических секций.

...