web-dev-qa-db-fra.com

Transactions de base de données Android Room

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.

17
rajath

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);
     }
 }
17
guness

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.

13
Pinakin

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!

0
David