A saga can be built using the SagaBuilder DSL.

This DSL is used to create saga actions, and define dependencies between them.

  1. Create a builder:
     import io.simplesource.saga.client.dsl.SagaDSL;
     import static io.simplesource.saga.client.dsl.SagaDSL;
     SagaBuilder<A> sagaBuilder = SagaDSL.createBuilder();
  2. Define some actions:
     SubSaga<A> a = sagaBuilder.addAction(actionIdA, actionCommandA, undoCommandA);
     SubSaga<A> b = sagaBuilder.addAction(actionIdB, actionCommandB, undoCommandB);
     SubSaga<A> c = sagaBuilder.addAction(actionIdC, actionCommandC, undoCommandC);

    A is the serializable action command type, typically something like SpecificRecord.

  3. Create dependencies between them:


    Execute a, then b, then c:


    Execute a, then b, c and d in parallel, then e:


    This can also be expressed as:

     a.andThen(inParallel(b, c, d)).andThen(e)

    Execute a, then b, c and d in series, then e. The following are equivalent:

     inSeries(a, b, c).andThen(d).andThen(e)
     inSeries(a, b, c, d, e)
     a.andThen(inSeries(b, c, d)).andThen(e)
     inSeries(List.of(a, b, c, d, e))

    The latter is useful when we have a sequence of actions of length only known at runtime.

    The andThen operator is associative. This means that the following are equivalent:




    This associativity property enables building larger sagas from smaller ones.

  4. Build the saga:
     Result<SagaError, Saga<A>> sagaBuildResult = sagaBuilder.build();

    If the Saga fails validation,such as has cyclical references or attempts to combine subsagas created with different builders, an error is created.

Scala DSL

A DSL is available for Scala users, loosely based on Akka Streams, equivalent to the Java DSL, but prettier and easier to read.


a ~> b ~> c
a ~> inParallel(b, c, d) ~> e
a ~> List(b, c, d).inParallel ~> e