Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLiteException "cannot commit - no transaction is active" while inserting with CONFLICT_REPLACE

I have some trouble updating my database.

This is the log:

12-02 16:18:57.502: D/Data Update(21218): Start updating databases
12-02 16:18:57.502: D/Data Update(21218): update size: 5
12-02 16:18:57.502: D/Data Update(21218): updating table cemeteries
12-02 14:28:51.877: I/SqliteDatabaseCpp(18826): sqlite returned: error code = 1802, msg = statement aborts at 13: [INSERT OR REPLACE  INTO cemeteries(id,name) VALUES (?,?)] , db=/data/data/de.l_one.app.shaufelv14/databases/poidatabase
12-02 14:28:51.877: E/SQLiteStatementCpp(18826): native_execute (step): errno = 2, error message = No such file or directory, handle = 0xdc0b70
12-02 14:28:51.877: I/SqliteDatabaseCpp(18826): sqlite returned: error code = 1, msg = statement aborts at 2: [COMMIT;] cannot commit - no transaction is active, db=/data/data/de.l_one.app.shaufelv14/databases/poidatabase
12-02 14:28:51.887: E/Data Update(18826): Update failed
12-02 14:28:51.887: E/Data Update(18826): android.database.sqlite.SQLiteException: cannot commit - no transaction is active
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteStatement.native_executeSql(Native Method)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:90)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:2006)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1946)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:764)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:273)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:115)
12-02 14:28:51.887: E/Data Update(18826):   at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1807)
12-02 14:28:51.887: E/Data Update(18826):   at de.l_one.app.shaufelv14.DataUpdater.update(DataUpdater.java:102)
12-02 14:28:51.887: E/Data Update(18826):   at de.l_one.app.shaufelv14.MainActivity$5.run(MainActivity.java:104)

This is the code I use to insert new Data:

int updateSize = 0;

// cvs is an ArrayList<ContentValues> array with each entry holding 
// the new values for a certain table
// I know I could use a Map but let's change one thing after another

for(ArrayList<ContentValues> list : cvs)
    updateSize += list.size();

Log.d(DEBUG_TAG, "Start updating databases");
Log.d(DEBUG_TAG, "update size: "+updateSize);

if(updateSize > 0) {

    dbHelper = ShaufelDatabaseHelper.getInstance(context);
    connection = dbHelper.getWritableDatabase();

    for(int i=0; i<cvs.length; i++) {
        String table;
        switch(i) {
            case 0: table = "cemeteries"; break;
            case 1: table = "customers"; break;
            case 2: table = "graves"; break;
            case 3: table = "orders"; break;
            case 4: table = "plants"; break;
            case 5: table = "plantevents"; break;
            case 6: table = "services"; break;
            case 7: table = "serviceevents"; break;
            default: throw new RuntimeException("wtf");
        }
        Log.d(DEBUG_TAG, "updating table "+table);

        for(ContentValues cv: cvs[i]) {
            // replace updated values, insert new ones
            connection.insertWithOnConflict(table, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
        }
    }
}

The strange thing about this is that the Exception is not thrown everytime. It's more like this:

If you start the App and log in, the Update works. If you then log out and back in (without closing the app) the update happens again but this time with the Exception.
If you close the app (not just pressing home but forcing a close with the android system) it will work again until you log out and back in.
The updates all contain the same data (we are currently testing this stuff) and it's run by the same code and yet it works only half the time.

This is run on Android 4.0.3 on a HTC Sensation.

like image 715
IchBinKeinBaum Avatar asked Dec 02 '12 20:12

IchBinKeinBaum


1 Answers

1802 is SQLITE_IOERR_FSTAT, which happens when the database file gets deleted while a connection is still open.

Are you doing any kind of file deletion in your update?

like image 150
CL. Avatar answered Nov 15 '22 20:11

CL.