During this exercise, you will:
- Orchestrate Activities using a Saga pattern to implement compensating transactions
- Handle failures with rollback logic
Make your changes to the code in the practice
subdirectory (look for TODO
comments that will guide you to where you should make changes to the code).
If you need a hint or want to verify your changes, look at the complete version
in the solution
subdirectory.
- In all terminals, change to the
exercises/sagas/practice
directory using the following command:cd exercises/sagas/practice
This Exercise uses the same structure as in the previous Exercises — meaning
that it will fail at the very end on ProcessCreditCard
if you provide it with
a bad credit card number.
Three new Activities have been created to demonstrate rollback actions.
updateInventory
is a new step that would run normally (whether or not the Workflow encounters an error).revertInventory
has also been added as a compensating action forupdateInventory
.refundCustomer
has been added as a compensating action forsendBill
.
- Review these new Activities at the end of the
PizzaActivities.java
andPizzaActivitiesImpl.java
file. None of them make actual inventory or billing changes, because the intent of this Activity is to show Temporal features, but you should be able to see where you could add functionality here. - Close the files.
Now you will implement a compensating action using Activities in your Temporal
Workflow using the Saga
object. Unlike other SDKs, the Temporal Java SDK provides
a custom Saga
class for handling compensations.
- Open
PizzaWorkflowImpl.java
. - Note that a Saga object,
saga
, has been added at the top of the Workflow Definition to keep track of each Activities compensating action. - The
updateInventory
Activity invocation has been added to your Workflow after validating an order, before thesendBill
Activity is called. The compensating action was added to thecompensations
object in the line above. Study this and use it for the next step. - Locate the invocation for the
processCreditCard
method. Add the appropriate compensation to thesaga
object, including the necessary parameters. - Add the following line to the
catch
block that is associated with theupdateInventory
andprocessCreditCard
Activities.saga.compensate();
- Compile your code using
mvn clean compile
.
Now that you've implemented the Saga pattern, it's time to see it in action. You'll first execute the Workflow successfully, then introduce an error causing a rollback.
- In one terminal, start the Worker by running:
mvn exec:java -Dexec.mainClass="pizzaworkflow.PizzaWorker"
- In another terminal, start the Workflow by executing:
mvn exec:java -Dexec.mainClass="pizzaworkflow.Starter"
- The Workflow should complete successfully. Verify its status is Completed in the Web UI.
- Kill the worker using
^C
- Open
Starter.java
- Locate the following line:
And delete the last 2 from the end. This will cause the
CreditCardInfo cardInfo = new CreditCardInfo("Lisa Anderson", "4242424242424242");
processCreditCard
Activity to fail, triggering a compensation. - Compile your code using
mvn clean compile
- Restart the Worker by running:
mvn exec:java -Dexec.mainClass="pizzaworkflow.PizzaWorker"
- In another terminal, start the Workflow again by executing:
mvn exec:java -Dexec.mainClass="pizzaworkflow.Starter"
- A short time after executing, you should see a stack trace appear stating that the Activity failed.
- Check the Workflow Execution in the Web UI. The Workflow will still be marked Failed, as the error that was raised in the Activity is re-thrown after the compensation is complete. Locate the following:
- Where did the Activity Task fail? What was the error message?
- Where did the compensations take place?
- Hint: Look for
Customer Refunded
andReverted changes to inventory
.
- Hint: Look for
You have now implemented the Saga pattern using Temporal.