Avec la nouvelle base de données de pièces sous Android, il existe une exigence selon laquelle deux opérations séquentielles doivent être effectuées:
removeRows(ids);
insertRows(ids);
Si je lance ceci, je vois (en examinant la base de données) qu'il manque certaines lignes - je suppose qu'elles sont en cours de suppression après leur insertion. à savoir. la première opération est parallèle à la seconde.
Si j'utilise un bloc de transaction, tel que celui-ci, tout va bien, la première opération semble se terminer avant la seconde:
roomDb.beginTransaction();
removeRows(ids);
roomDb.endTransaction();
insertRows(ids);
C'est aussi bien si je donne un sommeil entre les deux:
removeRows(ids);
Thread.sleep(500);
insertRows(ids);
Il ne semble pas y avoir beaucoup de documentation pour Room, et je me demandais si je devrais utiliser le bloc de transaction comme ci-dessus lorsque j'ai des opérations séquentielles à effectuer, ou existe-t-il un meilleur moyen de le faire.
EDIT: Après avoir souligné @CommonsWare, @Query
est asynchrone, alors que @Insert
et @Delete
sont synchrones. Compte tenu de cela, comment pourrais-je obtenir une requête qui supprime les lignes comme étant asynchrones:
@Query("DELETE from table WHERE id IN(:ids)")
int removeRows(List<Long> ids);
Selon la sortie de la construction, je reçois Deletion methods must either return void or return int (the number of deleted rows)
, si j'essaie d'envelopper le type de retour dans une variable Flowable
.
comme indiqué dans la documentation de Transaction , vous pouvez effectuer les opérations suivantes:
@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);
}
}
Comme @CommonsWare l'a souligné, @Query sont asynchrones, tandis que @Insert, @Delete, @Update sont synchrones.
Si vous souhaitez exécuter plusieurs requêtes dans une transaction unique, Room fournit également une méthode pour cela, comme indiqué ci-dessous.
roomDB.runInTransaction(new Runnable() {
@Override
public void run() {
removeRows(ids);
insertRows(ids);
}
});
J'espère que cela résoudra votre problème.
voici la solution à ce problème:
@Query("SELECT * FROM friend WHERE id = :id")
Friend getFriendByID(int id);
@Delete
void delete(Friend friend);
Friend friendToBeDeleted = friendDAO.getFriendByID(id);
friendDAO.delete(friendToBeDeleted);
Vous devez passer par deux étapes!