Позволяет ли одновременно создавать много транзакций в Android SQLite? - PullRequest
1 голос
/ 12 февраля 2012

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

Например: у меня есть 2 потока доступа к соединению с базой данных, возможно ли создать транзакцию в каждом потоке, и они не являются вложенными?

Ответы [ 2 ]

2 голосов
/ 11 июня 2012

Sqlite не поддерживает вложенные транзакции :

Транзакции, созданные с помощью BEGIN ... COMMIT, не вкладываются.Для вложенных транзакций используйте команды SAVEPOINT и RELEASE.

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

1 голос
/ 20 июня 2016

Создание двух отдельных транзакций в двух отдельных потоках не считается "вложенными транзакциями".

Каждый поток поддерживает свой собственный сеанс БД, который сопоставляется с 0 или 1 БД-соединениями (БД-соединения могут быть выбраны из пула соединений и возвращены ему, если соединение больше не требуется сеансом, поэтому прив любое время сеанс имеет соединение или нет, в зависимости от того, требуется ли он).

Поэтому каждый поток поддерживает свое собственное состояние транзакции независимо от других потоков.Источники подтверждают это:

.. / Android / sdk / sources / android-23 / android / database / sqlite / SQLiteDatabase.java:

// Thread-local for database sessions that belong to this database.
// Each thread has its own database session.
// INVARIANT: Immutable.
private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() {
    @Override
    protected SQLiteSession initialValue() {
        return createSession();
    }
};

.. / Android / sdk /sources / android-23 / android / database / sqlite / SQLiteSession.java:

 * <h2>About database sessions</h2>
 * <p>
 * Database access is always performed using a session.  The session
 * manages the lifecycle of transactions and database connections.
 * </p><p>

...

* Consequently, each thread
 * has its own session object and therefore its own transaction state independent
 * of other threads.

Итак, если у вас есть две транзакции, выполняющиеся в отдельных потоках, онине являются «вложенными», но полностью независимы и будут выполняться параллельно или сериализироваться в зависимости от режимов и типов задействованных транзакций (т. е. являются ли они отложенными, немедленными, исключительными и будут ли они считываться или записываться).

Однако для этого необходимо правильно использовать библиотеки SQLite для Android.

У меня есть два потока доступа к соединению с базой данных

Если это означает, что оба потока используюттот же SQLiteSession (хотя я не уверен, как это можно сделать, если это вообще возможно), тогда это вполне может привести к тупику.

Моя настройка:

  1. Единый контент-провайдер
  2. ConteПоставщик nt инициализирует переменную-член mDbHelper для SQLiteOpenHelper в своей функции onCreate ()
  3. . Вызовите mHelper.getReadableDatabase / getWriteableDatabase, как это требуется в методах запроса / вставки / ... / 10 /
  4. поставщика контента.состояние транзакции в каждом потоке, который использует контент-провайдер

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

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