nexora-saga
Orchestration-based saga coordinator. When a plan fails mid-execution, the saga rolls back all completed compensable steps in reverse topological order.
How it works
- Each step can declare a
compensateCapabilityIdin itsStepDefinition. - If the overall execution reaches a
FAILEDstatus,SagaOrchestratorcollects all completed steps that declared a compensation capability. - Compensations run sequentially in reverse topological order — the step closest to the failure compensates first, back toward the root.
- A failed compensation is logged and skipped; the remaining compensations still run.
Enabling sagas
NexoraEngine engine = NexoraEngine.builder()
.withSagaEnabled(true)
.build();
Declaring compensation on a step
new StepDefinition(
"charge",
"charge_card",
goal -> goal.contains("order"),
Map.of("orderId", InputBinding.fromContext("orderId")),
"chargeResult",
Set.of("validate"),
null,
Duration.ofSeconds(5),
"refund_card" // compensateCapabilityId
);
Writing a compensation capability
The compensation capability receives the original step's resolved inputs plus the full ExecutionContext. Use these to undo the work precisely.
public class RefundCardCapability implements Capability {
@Override
public CapabilityResult execute(CapabilityRequest request) {
String orderId = (String) request.inputs().get("orderId");
String chargeId = (String) request.context().getOutput("chargeResult");
paymentClient.refund(chargeId);
return CapabilityResult.success(Map.of("refunded", true));
}
}
Events
Subscribe to CompensationStartedEvent, CompensationCompletedEvent, and CompensationFailedEvent via NexoraEngine.subscribe() to observe rollback progress. See nexora-event for the full event reference.
What sagas do not cover
- Compensations that fail are logged and skipped; the engine does not retry them by default.
- Sagas are sequential — if you need parallel compensation, implement that logic inside the compensation capability itself.
- Sagas do not lock resources. If your capability interacts with external systems that require distributed locks, manage that at the application level.