0
votes

I have a Saga that creates a command which creates the Item aggregate.

I need to execute some other logic after the aggregates gets created so I've got a handler to deal with the ItemCreatedEvent.

It seems the ItemEventsHandler logic is not executed under the Saga instance locking. So I get another event associated to the Saga executing concurrently with the handler.

Is there a way to enforce the handler to be part of the same saga instance handling/execution? Am I missing something?

Using axon 4.3.3 with spring boot.

@Saga
public class OrderSaga {

    @Inject
    private transient CommandGateway commandGateway;

    @StartSaga
    @SagaEventHandler(associationProperty = "executionId")
    public void handle(OrderCreatedEvent event) {

        event.items.forEach(item -> {
            // Associate to Saga
            SagaLifecycle.associateWith("itemId", item.id);
            commandGateway.sendAndWait(new CreateItemCommand(event.groupId, event.schemaId, item));
        });
    }
}


@Aggregate
public class ItemAggregate {

    @AggregateIdentifier
    private String id;
    private String groupId;
        ...

    @CommandHandler
    public ItemAggregate on(CreateItemCommand command) {
        AggregateLifecycle.apply(new ItemCreatedEvent(
                command.id,
                command.groupId,
                ...));
    }

    @EventSourcingHandler
    protected void on(ItemCreatedEvent event) {
        this.id = event.id;
        this.groupId = event.groupId;
        ...
    }
}

@Service
public class ItemEventsHandler {

    @EventHandler
    protected void on(ItemCreatedEvent event) {
        // This needs to be executed under the Saga locking
    }
}

1
I do not fully comprehend why the ItemCreatedEvent needs to be handled within the same lock as the OrderSaga. Can you per chance elaborate what the use case for this is @matpiera?Steven
ItemEventsHandler needs to handle events in the same order as the Saga. It talks to a legacy system. What I'm doing now it's having Item as AggregateMember of Order. Does it make sense @Steven?matpiera
Having an Order aggregate contains Item entities does sound logical to me @matpiera, although it always "depends" on the domain whether something makes sense or not. Further more, although you state the events need to be handled in the same order, that still does not explain why that is a necessity in your system. At any point, event handling should be regarded as (conceptually) asynchronous. Thus imposing an order on when which component handles what is not really something I would suggest, unless there is a very clear and specific domain requirement on the matter.Steven
Thanks @Steven. I've revised the domain and it seems the order is not relevant here as the sequence of the messages will naturally be the right one.matpiera
That's good new @matpiera. Might be helpful to answer your own question here, so that others can follow your deduction if they hit the same problem. ;-)Steven

1 Answers

0
votes

It turned out that the order wasn't relevant at the time ItemEventsHandler is handling the event. The potential concurrency proven to be impossible as the second message is only produced after the first one has already been fully processed.

I've also found that in case of needing this non concurrent execution I could loop back the events to a Saga handler.