Android Room database transactions

rajath picture rajath · Jun 23, 2017 · Viewed 28.2k times · Source

With the new Room Database in Android, I have a requirement where there are two sequential operations that needs to be made:

removeRows(ids);
insertRows(ids);

If I run this, I see (on examining the db) that there are some rows missing - I assume they are being deleted after inserting. viz. the first operation is running in parallel to the second.

If I use a transaction block, such as this, then it's all fine - the first operation seems to complete before doing the second:

roomDb.beginTransaction();
removeRows(ids);
roomDb.endTransaction();

insertRows(ids);

It's also fine if I give a sleep in-between instead:

removeRows(ids);
Thread.sleep(500);

insertRows(ids);

There doesn't seem to be much documentation for Room, and was wondering if I should use the transaction block like the above when I have sequential operations to be done, or is there any better way of doing it.

EDIT: After @CommonsWare pointed out, @Query are asynchronous, while @Insert and @Delete are synchronous. In view of this, how would I get a query which deletes rows to be async:

@Query("DELETE from table WHERE id IN(:ids)")
int removeRows(List<Long> ids);

According to the build output I get Deletion methods must either return void or return int (the number of deleted rows), if I try to wrap the return type in a Flowable.

Answer

guness picture guness · Oct 12, 2017

As pointed out on documentation for Transaction, you can do following:

 @Dao
 public abstract class ProductDao {
    @Insert
    public abstract void insert(Product product);

    @Delete
    public abstract void delete(Product product);

    @Transaction
    public void insertAndDeleteInTransaction(Product newProduct, Product oldProduct) {
         // Anything inside this method runs in a single transaction.
         insert(newProduct);
         delete(oldProduct);
     }
 }