update transaction room example delete all android transactions android-database android-room

transaction - Transacciones de la base de datos de Android Room



room database android (3)

Con la nueva base de datos de salas en Android, tengo un requisito donde hay dos operaciones secuenciales que deben realizarse:

removeRows(ids); insertRows(ids);

Si ejecuto esto, veo (al examinar la base de datos) que faltan algunas filas, supongo que se eliminarán después de insertar. verbigracia. La primera operación se ejecuta en paralelo a la segunda.

Si uso un bloque de transacción, como este, entonces todo está bien, la primera operación parece completarse antes de hacer la segunda:

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

También está bien si doy un sueño intermedio en su lugar:

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

No parece haber mucha documentación para la Sala, y me preguntaba si debería usar el bloque de transacciones como el anterior cuando tengo que hacer operaciones secuenciales, o si hay alguna forma mejor de hacerlo.

EDITAR : Después de señalar @CommonsWare, @Query es asíncrono, mientras que @Insert y @Delete son síncronos. En vista de esto, ¿cómo obtendría una consulta que borra filas para que sean asíncronas?

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

De acuerdo con el resultado de la compilación, obtengo que los Deletion methods must either return void or return int (the number of deleted rows) , si intento ajustar el tipo de retorno en un Flowable .


Aquí está la solución a este problema:

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

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

Tienes que pasar por dos pasos!


Como @CommonsWare señaló, @Query es asíncrono, mientras que @Insert, @Delete, @Update son síncronos.

Si desea ejecutar varias consultas en una sola transacción, Room también proporciona un método para eso, como se menciona a continuación.

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

Espero que esto resuelva tu problema.


Como se indica en la documentación de Transaction , puede hacer lo siguiente:

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