Search code examples
androidsqliteandroid-sqliteandroid-room

"Cannot rollback - no transaction is active (code 1)" when using Android Room library on API 23 device


I am getting this error when I run my app on an API 23 device using the Room library. It happens on first launch, but I cannot get past my introduction in the app because it happens every time.

Fatal Exception: android.database.sqlite.SQLiteException: cannot rollback - no transaction is active (code 1)
       at android.database.sqlite.SQLiteConnection.nativeExecute(SQLiteConnection.java)
       at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:553)
       at android.database.sqlite.SQLiteSession.endTransactionUnchecked(SQLiteSession.java:439)
       at android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession.java:401)
       at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:522)
       at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:262)
       at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
       at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92)
       at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53)
       at androidx.room.SQLiteCopyOpenHelper.getWritableDatabase(SQLiteCopyOpenHelper.java:90)
       at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
       at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281)
       at com.diamonddevelopment.cardapp.data.CardMasterDao_Impl.getAllTags(CardMasterDao_Impl.java:1381)
       at com.diamonddevelopment.cardapp.data.AppRepository.getAllTags(AppRepository.kt:158)
       at com.diamonddevelopment.cardapp.activities.MainActivity$Companion$loadTags$1.run(MainActivity.kt:316)
       at java.lang.Thread.run(Thread.java:818)

This doesn't occur on API 24 and above. Is it a bug? This is how I create my room database:

fun getAppDatabase(context: Context): CardMasterDatabase? {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.applicationContext, CardMasterDatabase::class.java, FILE_NAME).createFromAsset("databases/$FILE_NAME").build()
            }
            return INSTANCE
        }

And how I use it:

 private var cardMasterDao: CardMasterDao? = null

    init {
        cardMasterDao = when {
            CardMasterDatabase.INSTANCE != null -> {
                CardMasterDatabase.INSTANCE!!.cardMasterDao()
            }
            else -> {
                CardMasterDatabase.getAppDatabase(context)!!.cardMasterDao()
            }
        }
    }

Edit:

getAllTags in AppRepository:

suspend fun getAllTags(): List<Tag> {
    return cardMasterDao!!.getAllTags()
}

getAllTags in CardMasterDao:

@Query("SELECT * FROM Tag")
suspend fun getAllTags(): List<Tag>

Solution

  • Some users had the same issue with API 22.

    You can try suggestions form the link:

    • Not using deferred foreign keys to relax constraints
    • Make sure your disk is not full
    • Use JournalMode.TRUNCATE
    • Catch the exception

    If you say it's gone with API 24, I guess this is a bug.

    Since you're not using any explicit transaction, I would say your best chance is to catch the exception explicitly.

    Hope this helps.