Search code examples
androidkotlinandroid-roomkotlin-coroutinescoroutinescope

Are RoomDb update/insert coroutine calls cancellable or will they complete regardless of cancellation?


Are roomDb calls cancellable? i.e. suspend functions have to be using yield() or check isActive() in order to react to cancellation. I'm trying to decide if it's safe to depend on a small (or rather large) roomDb transaction update to go through even if the viewModelScope is cancelled before transaction is complete.


Solution

  • Cancellation should be cooperative:

    Coroutine cancellation is cooperative. A coroutine code has to cooperate to be cancellable. All the suspending functions in kotlinx.coroutines are cancellable. They check for cancellation of coroutine and throw CancellationException when cancelled. However, if a coroutine is working in a computation and does not check for cancellation, then it cannot be cancelled.

    Speaking of Room DB under the hood they use withContext to switch between contexts, withContext is cancellable, therefore we can conclude that the RoomDB suspend calls are cancellable.

    To invoke suspend function in a non-cancellable fashion we can use withContext(NonCancellable) {} or create a global CoroutineScope, that will have an application lifetime, and use it to launch coroutines.