Транзакции базы данных 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);
Вы должны пройти два шага!