What is the idiomatic way for sagas to communicate with async services?


I am trying to understand how sagas should communicate with async or message bases services.
Sending the request to the service can be done as one likes.
But should we deliver the reply message/messages to the saga?
Should we install some “message to event” translator that publishes to the standard event bus?
Is it ok to use the standard event bus for “service events” as opposed to “storage events”?
Or can and should sagas use multiple event busses?

Seeking for help,

Hi Cal,

at this time, there is no means to send a message directly to a specific Saga instance. For now, the most reliable way is to publish an Event on your EventBus that is picked up by the Saga to process the result.
Alternatively, you could write your own mechanism that loads a Saga instance from the SagaRepository and executes logic on it. This solution prevents a message being published that is of interest to only a single component, but doesn’t give you the benefit of transparent distribution either.

One way that definitely won’t work, is calling the Saga instance that sent the request in some sort of callback to change it’s state. That Saga instance may have been serialized and “abandoned” already by the framework.



Hi Allard,

thanks, understood.

If I load the saga from the saga repository and offer my events to it:
Is there a danger that events from eventbus and my events are offered to the same saga and i have to synchronize them?


Hi Cal,

If I understand correctly, you’re trying to ensure that the saga isn’t called through the framework by events, when you’re trying to execute logic on it in your own SagaRepository implementation.
I’d guess a simple solution to overcome that would be to extend from the existing LockingSagaRepository in your own SagaRepository implementation.
The default SagaRepository in Axon is the AnnotatedSagaRepository, which also extends from LockingSagaRepository.
I do think you would have to use the same LockFactory for both your own SagaRepository implementation and the Axon AnnotatedSagaRepository for this set up to work though.

Hope this helps.



Actually, you don’t need to implement your own Repository. Just use the same SagaRepository instance as the Event handling mechanism does. That will also ensure proper locking.

Thank you very much. I try to summarize my alternatives.

(I am assuming a simple application with single eventbus and single event and saga jpa repository.)

  1. Use THE global event bus.

I use the same event bus (THE event bus) that my aggregates publish events on and that the sagas listens on
to send the response(s) of my as events to the sagas.

I tried that and if I interpret the errors correctly I have to add a @Transactional annotation because my response events are
persisted in the database like “normal” aggregate events are.
Is that interpretation correct?
It feels wrong to me storing this kind of events because they are just events of an request-response cycle and are not (yet) relevant
for changing the state of something. The saga should decide what and if some storage changing command is generated.

  1. Use THE SagaRepository instance directly.

By using this I get storage of sagas for free including locking for synchronized access with THE eventbus events.
I expect that I have to provide a transaction context, too, because of the JPA-Nature of saga repository.

I will give this a try.

Because of the way sagas are typically executed synchronously within database transactions I assume the
rules for DB transaction apply normally:
Don’t execute long-running synchronous calls.

Please correct me when I am wrong!


I am trying to get access to the SagaRepository (or could I use the AnnotatedSagaManager instead).
I don’t find a way to get an instance on one of them.


I have created issue 303 to resolve this (https://github.com/AxonFramework/AxonFramework/issues/303). At the moment, only the Configuration bean is exposed, but even that bean doesn’t give access to the Repository or SagaManager.