# Saga Compensate vs Workflow CancellationScope

**URL:** https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297
**Category:** Community Support
**Tags:** java-sdk
**Created:** [January 12, 2021, 8:54pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297 "2021-01-12T20:54:24Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Grast](https://avatars.discourse-cdn.com/v4/letter/g/dec6dc/32.png) [@Grast](https://community.temporal.io/u/Grast)
#### Post date: [January 12, 2021, 8:54pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297/1 "2021-01-12T20:54:25Z")

</div>

I have confusion regarding use case of Saga compensate vs workflow CancellationScope. Looks like both can perform cleanup for workflow and sub actvities. Any insight or suggestion?

---

<div class="post-metadata">

### Author: ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)
#### Post date: [January 12, 2021, 9:02pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297/2 "2021-01-12T21:02:15Z")

</div>

Saga is a way to dynamically accumulate compensations based on the code path of the workflow. Cancellation is a way to interrupt workflow execution at any point.

```java
    Saga saga = new Saga(sagaOptions);
    try {
      String carReservationID = activities.reserveCar(name);
      saga.addCompensation(activities::cancelCar, carReservationID, name);

      if (bookHotel) {
        String hotelReservationID = activities.bookHotel(name);
        saga.addCompensation(activities::cancelHotel, hotelReservationID, name);
      }
      String flightReservationID = activities.bookFlight(name);
      saga.addCompensation(activities::cancelFlight, flightReservationID, name);
    } catch (TemporalFailure e) {
      Workflow.newDetachedCancellationScope(() -> saga.compensate()).run();
      throw e;
    }

```

In the sample above if `bookHotel` is false it is not going to include `cancelHotel` activity invocation when `saga.compensate` is called. Note that the `TemporalFailure` can be either an `ActivityFailure` or `CanceledFailure` if the workflow is canceled while executing any of the reservation activities.

---

<div class="post-metadata">

### Author: ![Grast](https://avatars.discourse-cdn.com/v4/letter/g/dec6dc/32.png) [@Grast](https://community.temporal.io/u/Grast)
#### Post date: [January 12, 2021, 10:37pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297/3 "2021-01-12T22:37:06Z")

</div>

> [@maxim](#):
>
> Saga is a way to dynamically accumulate compensations based on the code path of the workflow. Cancellation is a way to interrupt workflow ex

Thanks for the quick clarification. I have two follow questions.  
1.If I only call saga.compensate() in the catch block( without calling Workflow.newDetachedCancellationScope(()), What will be the difference?

2.You stated that " `TemporalFailure` can be either an `ActivityFailure` or `CanceledFailure`". Suppose there was failure during bookFlight activity and compensate cancelCar and cancelHotel. Suppose cancelHotel failed as well may be network issue. As per this code, it will invoke compensate again for cancelCar and cancelHotel .Create a cyclic loop, is my understanding correct?

---

<div class="post-metadata">

### Author: ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)
#### Post date: [January 12, 2021, 10:45pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297/4 "2021-01-12T22:45:30Z")

</div>

1. If the root cancellation scope is cancelled because the whole workflow is cancelled, any attempt to execute activity or child workflow is going to fail with CanceledFailure. So if a compensation requires such calls it is going to fail. I filed [an issue](https://github.com/temporalio/sdk-java/issues/305) to execute compensations in a disconnected scope by default.

2. I don’t see where in the above code a loop can be found. The behavior in case of a compensation failure is configured through `Saga.Options.ContinueWithError`. If it is set to `true` a compensation failure would be ignored and all other compensations executed. If it is set to `false` then an exception will be thrown from the catch block without executing other compensations and workflow is going to fail (if it fails to handle the exception). Note that your example should never execute this functionality as any compensation activity is expected to have an appropriate retry policy to not fail on intermittent errors like network outages.

---

<div class="post-metadata">

### Author: ![madhu](https://avatars.discourse-cdn.com/v4/letter/m/a8b319/32.png) [@madhu](https://community.temporal.io/u/madhu)
#### Post date: [January 15, 2021, 5:29pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297/5 "2021-01-15T17:29:19Z")

</div>

just a quick question, when the compensate happens will those also be retired based on the actitvity/retry options?

---

<div class="post-metadata">

### Author: ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)
#### Post date: [January 15, 2021, 5:58pm UTC](https://community.temporal.io/t/saga-compensate-vs-workflow-cancellationscope/1297/6 "2021-01-15T17:58:58Z")

</div>

Compensations are just callbacks. The code in these callbacks is a normal workflow code. So if it invokes activities they obey the configured retry options.
