Example of using sequence numbers to handle concurrency issues.

Hi,

COMMENT
I am new to the Axon Framework. I like it very much. However, I have to admit that if I did not have someone one my team who have experience with it, I may not be able to use it because, though there is very verbose documentation on the theory / thought process of why thing are done in axon, there are almost no documentation on how to actually implement it, make practical use of it. Given the quality of Axon’s implementation, this is very, very frustrating.

MY QUESTION
I would like to use the Axon sequence numbers. I think they prevent stale data updates to the event store; they essentially server the same function as version numbers do in support of optimistic locking in JPA. I found my way to section 5.3.2 in the Axon Reference Guide. What is described there is exactly what I want to do. However, there is no example of how to do it. I also took a look at the advanced conflict revision section–I don’t want to resolve the conflicts programmatically for my use case. I just want to be able to let the user know that the conflict has occurred. Also, looked at the Address Book sample app and did not see an example there either. I would love to make use of sequence numbers and here are me questions:

How do I interact with the Axon API to make use of sequence numbers?
a. Do I need to send the sequence number in as part of the commands?
b. Do I need to include the sequence number as a data member in my domain objects?
c. Should I include the sequence number in the domain events?
d. Should I provide the initial sequence number or is there some way to have Axon start it off?
e. Will the sequence number be incremented by axon (or, I suspect the underlying JPA) or do I have to manage the increments myself?
f. I notice that there is a get version method on the AbstractAggregateRoot class. How does that relate to the sequence number?
g. What is the relationship between the eventRevision and the sequenceNumber that I see on the DomainEvent class?

I am requesting an example / code snippets for two scenarios (the examples could answer questions a through e):
- the creation sequence from the command being created and being send through the command gateway until the resulting events are applied in the domain,
- the update sequence from the command being created and being send through the command gateway until the resulting events are applied in the domain.

Thank you for this wonderful framework and thank you for helping me to make use of it,
Jan

Hi,

COMMENT
I am new to the Axon Framework. I like it very much. However, I have to admit that if I did not have someone one my team who have experience with it, I may not be able to use it because, though there is very verbose documentation on the theory / thought process of why thing are done in axon, there are almost no documentation on how to actually implement it, make practical use of it. Given the quality of Axon’s implementation, this is very, very frustrating.

MY QUESTION
I would like to use the Axon sequence numbers. I think they prevent stale data updates to the event store; they essentially server the same function as version numbers do in support of optimistic locking in JPA. I found my way to section 5.3.2 in the Axon Reference Guide. What is described there is exactly what I want to do. However, there is no example of how to do it. I also took a look at the advanced conflict revision section–I don’t want to resolve the conflicts programmatically for my use case. I just want to be able to let the user know that the conflict has occurred. Also, looked at the Address Book sample app and did not see an example there either. I would love to make use of sequence numbers and here are me questions:

How do I interact with the Axon API to make use of sequence numbers?
a. Do I need to send the sequence number in as part of the commands?
b. Do I need to include the sequence number as a data member in my domain objects?
c. Should I include the sequence number in the domain events?
d. Should I provide the initial sequence number or is there some way to have Axon start it off?
e. Will the sequence number be incremented by axon (or, I suspect the underlying JPA) or do I have to manage the increments myself?
f. I notice that there is a get version method on the AbstractAggregateRoot class. How does that relate to the sequence number?
g. What is the relationship between the eventRevision and the sequenceNumber that I see on the DomainEvent class?

h. When and event sourced member is updated and its sequence number is advanced, is the sequence number of its aggregate root also advanced? (This question was added)

Hi,

see my response inline.

Thank you for your response. I am working with it now. I will post some code snippets once I get it working.

I have another question concerning sequence numbers …

My Scenario
When a user logs in, I want to register a logged in event . I have created the following:

  • A RegisterUserLoginCommand ,a pojo which accepts the aggregate sequence from my controller.
  • A UserCommandHandler that handles my command and loads the User that corresponds to the given sequence from the EventStore.
  • A User domain object that extends AbstractAnnotatedAggregateRoot. The User has a registerLogin method that applies an UserLoggedInEvent.
  • The UserLoggedInEvent is handled in two places:
  • One is within the User domain object itself. From here, the AggregateRoot.getLastCommitedSequenceNumber is available.
  • the other is one the query side of my application in my UserChangeListener where I am not sure how to get access to the last committed sequence number.

The Question
How do I send the last committed sequence number to the query side? The reason I want to send the sequence number to the query side is so that I can load the most recent version of User the next time a person logs in. I can’t send the sequence number with the event because the sequence number has not yet been incremented at the time it is applied. I notice that the sequence number is available on the DomainEvent class. I if changed my UserLoggedInEvent pojo to extend the DomainEvent class, would that be an appropriate way of getting the most recent sequence number to the query side. I am trying to work within the architectural constraint of not exposing my domain module to the query side. I only want to expose the domain API which includes the events.

Thanks again,
Jan

Hi,

Axon wraps your Event object in an EventMessage (or when applied by an aggregate, a DomainEventMessage). Your event object is the payload of this message. Next to the payload, you can attach meta-data. Axon also adds some extra information, such as the sequence number.

In your @EventHandler methods (where the first parameter is the type of payload you expect), you can add extra parameters. In Axon 2.0, the best way to get to the sequence number is by adding a parameter of type DomainEventMessage and get the sequence number from there. In Axon 2.1 you will be able to add a parameter of type long (or Long) and annotate it with @SequenceNumber.

Cheers,

Allard

Hi Allard,

the above scenario describe the standard concept of issuing (applying) the events out from the business logic methods of the Aggregates,in which the Aggregate’s state is being chenged.

In our case, however the Aggregate is a pure entity withut business logic, for historical reasons. The business logic is “outsourced” to workflows, that are associated with the commands. Those are processed by a generic external command handler, that publishes the GenericDomainEventMessages by calling the publish() method. The question is, how should we let Axon set the sequence number of the event in this case? It seems we are forced to compute it ourselves, because all constructors/methods of GenericDomainEventMessage require it. Why does Axon not compute and set the sequence number in this case internally as in the above mentioned standard scenario?

br
Marek

Hi Marek,

So if I understand correctly, you are using the CommandBus and EventBus, but not the Repository to have (Event Sourced) Aggregates in your system?
I could argue that if that’s the case, you thus don’t have a Command Model which publishes an event, but a service which publishes an event.

By default that means you’d publish Event Message rather than Domain Event Message, as they’re not originating from a Command Model / Domain Model.
The sequence number in it’s place is the sequence number of the Nth event published by an Aggregate.
As you’re not publishing events from an Aggregate in that sense, you thus don’t have a sequence number for that specific Aggregate.

So, Axon does calculate it internally, but for instances of DomainEventMessages, it doesn’t do that out of the box for regular Event Messages.

Although I obviously not 100% now the intention of this implementation (probably Allard could enlighten that if required), but my guess is that this behavior is by design to make a deviation between Domain Event Messages and normal Event Messages.

Hope this clarifies.

Cheers,

Steven

Hi Steven,

actually, we have an Event Store (SQL) and Repository, but our Aggregate is - at least in the command handler not rebuild out of the event store, but rather from the Read Model. We plan to rebuild the Aggregates from the Event store just in selected use cases (for selected commands), where we need to recreate a historical version of the Aggregate or revoke any of the already executed commands. To achieve that, we probably need to implement code, which will get the whole event stream from the event store for a particular aggregate (starting from a snapshot),filter it to the intended subset and reapply each event to rebuild the desired version of the aggregate.

So, I think, we have a de-facto “event sourced aggregate”, the matter is just that it is not always event sourced. May be, we should really even than make our Aggegate to be an EventSourcedAggregate and apply the events from there to get the sequencing by Axon out of the box.