Android Coroutine: Revertir todos los trabajos si alguno de ellos falla.
Supongamos
Trabajo1 -> hacer la primera llamada a la API
Trabajo2 -> guardar los datos en la base de datos (ROOM)
Trabajo3 -> hacer la segunda llamada a la API
Trabajo4 -> guardar los datos en la base de datos (ROOM)
Trabajo5 -> procesar los datos (u otra tarea)
Supongamos que el Trabajo3 falló (por una excepción, una respuesta inválida, el usuario lo canceló manualmente, la aplicación se cerró…) entonces revertir también el Trabajo2 y el Trabajo1.
Actualmente, estoy utilizando:
val mainJob = CoroutineScope(IO).launch{
val result1 = async{}.await()// Llamada a la API, digamos: Trabajo1
val result2 = async{}.await()// Guardar los datos en la base de datos, digamos: Trabajo2
val result3 = async{result1//usar result1 en este trabajo para hacer la llamada a la API}.await()// Llamada a la API, digamos: Trabajo3
val result4 = async{}.await()// Guardar los datos en la base de datos, digamos: Trabajo4
val result5 = async{}.await()// alguna tarea, digamos: Trabajo5
}
El problema con este enfoque es que si se cancela mainJob en result3 o result4, no se revierten los datos almacenados en la base de datos en el momento de la ejecución de Trabajo2.
Por favor, no me den una respuesta como guardar los datos de Trabajo2 en la memoria de la aplicación en alguna variable y almacenarlos en la base de datos solo cuando se ejecuten todos los trabajos correctamente.
Necesito almacenar los datos en la base de datos en el Trabajo2.
davy.ai
Para manejar el caso en el que Job3 falla y necesitemos revertir Job2 y Job1, podemos utilizar una combinación de try-catch y la función withContext en Coroutines. Aquí está el código actualizado:
En este código actualizado, envolvemos los trabajos de la coroutine en un bloque try-catch para manejar cualquier excepción que pueda ocurrir. Si ocurre una excepción en Job3, la capturamos y usamos la función
withContext
para ejecutar el proceso de reversión en un contexto separado (en este caso, el despachador por defecto). Dentro del bloquewithContext
, podemos realizar las acciones necesarias para revertir Job2 y Job1, como eliminar los datos de la base de datos.Al utilizar este enfoque, aseguramos que los datos almacenados en la base de datos sean consistentes con la ejecución de los trabajos de la coroutine, incluso en los casos en los que se produzca una excepción.