The documentations says
The transaction will be marked as successful unless an exception is thrown in the method body.
It doesn't actually say that the exception will be managed, although the ROLLBACK will i.e. the setTransactionSuccessful is skipped and the endTransaction is executed. If you look at the generated code, say for example the coded method is :-
@Transaction
public boolean update4(Bookmark b1, Bookmark b2) {
if (update(b1) > 0) {
if (update(b2) < 1) {
abort(b1);
return false;
}
} else {
abort(b1);
return false;
}
return true;
}
The code generated by Room is :-
@Override
public boolean update4(final Bookmark b1, final Bookmark b2) {
__db.beginTransaction();
try {
boolean _result = AllDao_Impl.super.update4(b1, b2);
__db.setTransactionSuccessful();
return _result;
} finally {
__db.endTransaction();
}
}
there is no catch, so you need to handle exceptions accordingly.
Consider the following (modified version of the previous answer given):-
b1.setPostUrl("YetAnotherURL");
b5.setPostTitle("P5");
b5.setPostUrl("U5");
try {
dao.update4(b1, b5);
}
catch (Exception e) {
e.printStackTrace();
}
logInfo("-D1");
dao.update4(b1,b5);
logInfo("-D2");
Basically the same update, which will not update (return 0) as the id doesn't exist, run twice. The difference being that the first is in a try/catch block.
The result from the log :-
2021-07-09 12:04:38.344 W/System.err: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: mylist_data.ID (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
2021-07-09 12:04:38.348 W/System.err: at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
2021-07-09 12:04:38.349 W/System.err: at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
2021-07-09 12:04:38.349 W/System.err: at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
2021-07-09 12:04:38.349 W/System.err: at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
2021-07-09 12:04:38.349 W/System.err: at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
2021-07-09 12:04:38.349 W/System.err: at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.java:114)
2021-07-09 12:04:38.349 W/System.err: at a.a.so67958704javaroomconvertexistingdb.AllDao_Impl.abort(AllDao_Impl.java:133)
2021-07-09 12:04:38.349 W/System.err: at a.a.so67958704javaroomconvertexistingdb.AllDao.update4(AllDao.java:40)
2021-07-09 12:04:38.350 W/System.err: at a.a.so67958704javaroomconvertexistingdb.AllDao_Impl.access$001(AllDao_Impl.java:22)
2021-07-09 12:04:38.350 W/System.err: at a.a.so67958704javaroomconvertexistingdb.AllDao_Impl.update4(AllDao_Impl.java:159)
2021-07-09 12:04:38.350 W/System.err: at a.a.so67958704javaroomconvertexistingdb.MainActivity.onCreate(MainActivity.java:78)
....
2021-07-09 12:04:38.353 D/BMINFO-D1: ID = 1 PostTitle = P1 PostURL =AnotherURL
2021-07-09 12:04:38.353 D/BMINFO-D1: ID = 2 PostTitle = P2 PostURL =U2
2021-07-09 12:04:38.353 D/BMINFO-D1: ID = 3 PostTitle = P3 PostURL =U3
2021-07-09 12:04:38.353 D/BMINFO-D1: ID = 4 PostTitle = P4 PostURL =U4
2021-07-09 12:04:38.355 D/AndroidRuntime: Shutting down VM
2021-07-09 12:04:38.358 E/AndroidRuntime: FATAL EXCEPTION: main
Process: a.a.so67958704javaroomconvertexistingdb, PID: 14230
java.lang.RuntimeException: Unable to start activity ComponentInfo{a.a.so67958704javaroomconvertexistingdb/a.a.so67958704javaroomconvertexistingdb.MainActivity}: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: mylist_data.ID (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
Noting that the first exception is caught and printed and is NOT a FATAL EXCEPTION, the 2nd is.