Transactions and Sagas

Hi All,

Trying to wrap my head around the concept of Sagas, reading through the documentation I saw this

Because Transactions are often Thread bound, you may need to configure a Transaction Manager with the SagaManager. This transaction manager is invoked before and after each invocation to the Saga Repository and before and after each batch of Events has been processed by the Saga itself.

From the above I understand that there is a transaction created for persisting the state of each Saga, Is my understanding correct ?

However "and before and after each batch of Events has been processed by the Saga itself."
is quite confusing to me ?, what do we mean by batch of Events ?

In the below code – how many transactions would be created ?

public class OrderManagementSaga extends AbstractAnnotatedSaga {

    private boolean paid = false;
    private boolean delivered = false;
    private transient CommandGateway commandGateway;

    @StartSaga
    @SagaEventHandler(associationProperty = "orderId")
    public void handle(OrderCreatedEvent event) {
        // client generated identifiers <img src="http://www.axonframework.org/docs/2.3/images/callouts/1.png" alt="(1)">
        ShippingId shipmentId = createShipmentId();
        InvoiceId invoiceId = createInvoiceId();
        // associate the Saga with these values, before sending the commands <img src="http://www.axonframework.org/docs/2.3/images/callouts/2.png" alt="(2)">
        associateWith("shipmentId", shipmentId);
        associateWith("invoiceId", invoiceId);
        // send the commands
        commandGateway.send(new PrepareShippingCommand(...));
        commandGateway.send(new CreateInvoiceCommand(...));
    }

    @SagaEventHandler(associationProperty = "shipmentId")
    public void handle(ShippingArrivedEvent event) {
        delivered = true;
        if (paid) {
            end(); <img src="http://www.axonframework.org/docs/2.3/images/callouts/3.png" alt="(3)">
        }
    }

    @SagaEventHandler(associationProperty = "invoiceId")
    public void handle(InvoicePaidEvent event) {
        paid = true;
        if (delivered) {
            end(); <img src="http://www.axonframework.org/docs/2.3/images/callouts/4.png" alt="(4)">
        }
    }

Hi,

the number of transactions created depends mainly on the infrastructure components you use. If you use the SimpleEventBus and SimpleCommandBus, everything runs in a single transaction. It’s only when the Sagas run asynchronously, that extra transactions are being created.

When using an asynchronous saga manager in combination with the SimpleEventBus and SimpleCommandBus, each event will create (at most) one transaction. When multiple events arrive in quick succession, Axon will batch them together in a single transaction. The “CreateOrderCommand” will create one transaction, producing the OrderCreatedEvent. When that arrives at the SagaManager, that event is processed in another thread, and another transaction. That transaction loads the saga, and processes it. Since the SimpleCommandBus will use an existing transaction, when present, the PrepareShippingCommand and CreateInvoiceCommand will be processed in the same transaction. The events, however, are again asynchronously processed by the saga manager, creating a transaction for each event (unless batching decides to create a single one for both).

Basically, only when Axon starts processing something in another thread, it will create a transaction for that new job. Otherwise, it simply uses the transaction already bound to that thread (unless the transaction manager explicitly creates a new one, of course).

Hope this clarifies things a bit.
Cheers,

Allard