Условие медленной миграции в Android Room - PullRequest
0 голосов
/ 09 октября 2019

Версия для комнаты 2.2.0-rc01 Версии для Android 7.1, 8.1

У меня миграция немного большая. Добавление пары таблиц, индексов и т. Д. При запуске блокирует базу данных. Так как это занимает некоторое время, оно вызывает android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5) во всех остальных частях приложения.

Есть ли способ дождаться окончания миграций, прежде чем пытаться использовать БД?

Сокращенная миграция:

  try {
            // database.beginTransaction()

            database.execSQL("ALTER TABLE DeviceItem ADD COLUMN #### INTEGER NOT NULL DEFAULT 0")
            database.execSQL("ALTER TABLE DeviceItem ADD COLUMN #### TEXT NOT NULL DEFAULT ''")

            database.execSQL("CREATE INDEX IF NOT EXISTS ### ON #### (###, ###)")
           //helper method that just creates the table
            createLocalityTable(database)
            //database.setTransactionSuccessful()


        } catch (e: SQLiteException) {
            Crashlytics.logException(e)
            throw e
        } catch (e: Throwable) {
            Crashlytics.logException(e)
            throw e
        } finally {
            // database.endTransaction()
            database.close()
        }

Это моя база данных приложения singleton

package com.company.app.data

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters

@Database(entities = [someClass::class, otherClass::class, etc::class], version = 3)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun somethingDao(): somethingDao

    @Synchronized
    override fun close() {
        if (INSTANCE != null) {
            super.close()
            INSTANCE = null
        }
    }
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        var canGo = false
        fun getAppDatabase(context: Context): AppDatabase? {
            val tempInstance = INSTANCE
            if (tempInstance != null) {
                return tempInstance
            }

            synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        AppDatabase::class.java,
                        "myDb"
                ).addMigrations(MIGRATION_X_X).build()

                INSTANCE = instance
                return instance
                }
        }
    }
}

1 Ответ

0 голосов
/ 10 октября 2019

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

Комната не ожидает закрытия базы данных после завершения миграции, поэтому считает, что что-то еще закрыло / получило доступ к базе данных.

Более того, нет необходимости использовать транзакции как Romвызывает метод migrate внутри самой транзакции.

Этот метод уже вызывается внутри транзакции, и эта транзакция может фактически быть составной транзакцией всех необходимых миграций.

Миграция

Я бы посоветовал использовать код миграции: -

        database.execSQL("ALTER TABLE DeviceItem ADD COLUMN #### INTEGER NOT NULL DEFAULT 0")
        database.execSQL("ALTER TABLE DeviceItem ADD COLUMN #### TEXT NOT NULL DEFAULT ''")
        database.execSQL("CREATE INDEX IF NOT EXISTS ### ON #### (###, ###)")
        //helper method that just creates the table
        createLocalityTable(database)
  • Метод createLocalityTable также не должен закрывать базу данных.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...