Транзакции базы данных Android Room

С новой базой данных на базе Android в Android у меня есть требование, где необходимо выполнить две последовательные операции:

removeRows(ids);
insertRows(ids);

Если я запустил это, я вижу (при рассмотрении db), что некоторые строки отсутствуют - я предполагаю, что они удаляются после вставки. а именно первая операция выполняется параллельно со вторым.

Если я использую транзакционный блок, например, этот, то все отлично - первая операция, кажется, завершается, прежде чем делать вторую:

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

insertRows(ids);

Это также прекрасно, если я вместо этого даю сон:

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

insertRows(ids);

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

EDIT. После того, как @CommonsWare указал, @Query являются асинхронными, а @Insert и @Delete являются синхронными. В связи с этим, как бы получить запрос, который удаляет строки async:

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

В соответствии с результатом сборки я получаю Deletion methods must either return void or return int (the number of deleted rows), если я попытаюсь обернуть возвращаемый тип в Flowable.

Ответ 1

как указано в документации для Transaction, вы можете сделать следующее:

 @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);
     }
 }

Ответ 2

Как отмечалось в @CommonsWare, @Query являются асинхронными, а @Insert, @Delete, @Update являются синхронными.

Если вы хотите выполнить несколько запросов в одной транзакции, Room также предоставляет метод для этого, как указано ниже.

roomDB.runInTransaction(new Runnable() {
        @Override
        public void run() {
            removeRows(ids);
            insertRows(ids);
        }
    });

Я надеюсь, что это решит вашу проблему.

Ответ 3

вот решение этой проблемы:

@Query("SELECT * FROM friend WHERE id = :id")
Friend getFriendByID(int id);
@Delete
void delete(Friend friend);

Friend friendToBeDeleted = friendDAO.getFriendByID(id);
friendDAO.delete(friendToBeDeleted);

Вы должны пройти два шага!