Same Saga type with different processinggroup (processor) names on different nodes

I am using axon 4.2, single database (single saga store/event store/token store etc.)

We have 2 QA environments and I deployed the same code into both of them. I dynamically assigned different processing group names to Saga based on the environment, say one is QA1SagaProcessor and the other is QA2SagaProcessor for the same Saga Class. Now events get processed by both processors, which is using the same Saga class. My questions is: an event with a certain associationProperty value comes in, will there be two Saga instances at a single point of time, one from each processor in one environment? Or is there still only one Saga instance at a single point of time, from one environment, it finishes processing, serializes into Saga store, then another Saga instance from the other environment de-serializes and process the same event again?

From what I am observing, since the tracking processor names are different (thus different tracking token), there will be two Saga instances at the same time. I am not sure about when serialize/de-serialize will happen (seems to me it is unpredictable or is it done every time an events coming in?), the final value stored in Saga_entry table is also unpredictable depending on which instance serializes into table last. (We have other events coming in, one event is just a very simplified example)

Can Axon guru confirm if my observation is correct? I understand that if I just leave the processor name alone (so they are the same value, SagaProcessor, in both environments), then there will be only one Saga instance handling one event at a single point of time (A saga instance is never invoked concurrently by multiple threads. Therefore, a sequencing policy for a saga is irrelevant. Axon will ensure each saga instance receives the events it needs to process in the order they have been published on the event bus.) My dilemma is that I have a requirement that I must dictate a Saga instance from a specific environment to process an event based on a certain attribute on the event itself. I don’t know the algorithm how axon cluster pick a Saga instance. (How is the processor competing for token?)

So no one is able to give any suggestions? Let me simplified the question a little bit. Let’s say I have two apps with same code base, the only difference between them is they use different processing group names. But they both point to the same database (meaning share the same axon tables, we have only one schema). So now when one event is published, both apps are going to process that event. Any potential issues with this set up? My testers report that occasionally they see even though the events are stored in domain_event_entry table, but they are not processed by processor, which I can’t explain. I would expect both apps are processing the events.

Hi Chun,

In the described set up you would indeed duplicate your Saga instances.
Although the same association property set-up within your Saga code ensures similar associations are made, that does not dictate the Saga Id which will be created to store the serialized Saga with.
It would thus be better to keep the processor name of the Saga instance identical on all instances of said application.

Note that your statement that the sequencing policy is irrelevant for Sagas is incorrect.
Let’s assume you have two application instances A and B, both with a Tracking Event Processor serving events to your Saga, which we call “MySagaProcessor”.
You’ve configured your “MySagaProcessor” such that you have four segments and two threads.

In this set up app-instances A and B will both have two active threads, each claiming one of the four segments.

The SequencingPolicy dictates whether a given event should be handled by a given segment.
As with the above scenario there are four segments, that would mean the SequencingPolicy is still in charge of stating “this event belongs to this segment”, regardless of whether those events are intended for Query Model adjustments or Saga processing.

To answer one of your later questions:

How is the processor competing for token?

The TrackingEventProcessor (TEP) currently does a best effort on this, no specifics in place.
Thus if a TEP starts up and its threads start up, they’ll try to claim a segment, period.

If you want to have directional handling of messages, it might be interesting to check out the tagging functionality.
In Axon Server’s context this allows for location awareness essentially, which to me sounds like the thing you need.

Hope this helps you further Chun.


Hi Chun,

I must have had a massive brainfart yesterday, but this statement of mine:

Note that your statement that the sequencing policy is irrelevant for Sagas is incorrect.

is the thing which is incorrect… How recollection later in a day can bring epiphanies.

So, let me provide you with the actual approach of the AnnotatedSagaManager.

As you rightfully noted, the AnnotatedSagaManager does not deal with the SequencingPolicy.
The EventHandlerInvoker interface, of which the AnnotatedSagaManager is an implementation, is where the handle method is defined.
To be exact, the handle method is defined as follows:


  • Handle the given {@code message} for the given {@code segment}.
  • Callers are recommended to invoke {@link #canHandle(EventMessage, Segment)} prior to invocation, but aren’t
  • required to do so. Implementations must ensure to take the given segment into account when processing messages.
  • @param message The message to handle
  • @param segment The segment for which to handle the message
  • @throws Exception when an exception occurs while handling the message
    void handle(EventMessage<?> message, Segment segment) throws Exception;

The Segment referenced in this method is the/one of the segment(s) of the TrackingEventProcessor in this case.
The AbstractSagaManager’s implementation of the handle method further on uses the segment in conjunction with the saga identifier to verify whether it should handle the event yes/no.
This thus means that the Saga Identifier will be used to define whether an event will be handled by a thread/node combination.

FYI, the SimpleHandlerInvoker/MultiEventHandlerInvoker are implementations of this interface which use the SequencingPolicy as described in my previous post.
I think my mix up occurred to my recent efforts on those two classes…again my apologies for sharing this unintended mix up.

Concluding, I still hope all of this helps you out Chun!