Sometime an EventStoreException occurs mentioning the event couldn't be stored because it has the same sequence as another event in the aggregate.
This happens when EventA and EventB almost have the same timestamp.
CommandA is sent by a controller and CommandB is sent by a Saga within a DeadlineHandler.
So the handling of the deadline fails with the EventStoreException is logged, but not retried.
Would it help if we configure the Saga with a PropagatingErrorHandler?
Events table:
timestamp | aggregate_id | seq | type
| | |
2020-11-30T15:14:51.345541552Z | b02a5364-ee34-431a-ab1a-6c59bb937845 | 0 | MyAggregate
2020-11-30T15:14:52.06794746Z | b02a5364-ee34-431a-ab1a-6c59bb937845 | 1 | MyAggregate
Exception details:
org.axonframework.eventsourcing.eventstore.EventStoreException: An event for aggregate [b02a5364-ee34-431a-ab1a-6c59bb937845] at sequence [1] was already inserted
java.sql.BatchUpdateException: Batch entry 0 INSERT INTO events
(event_id, aggregate_id, sequence_number, type, timestamp, payload_type, payload_revision, payload, metadata)
VALUES
('d5be369e-5fd0-475e-b5b6-e12449a4ed04',
'b02a5364-ee34-431a-ab1a -6c59bb937845',
1,
'MyAggregate',
'2020-11-30T15:14:52.067871723Z',
'MyEvent',
NULL,
'{"payload":"payload"}',
'{"metaData":"metaData"}')
was aborted: ERROR: duplicate key value violates unique constraint "uk_aggregate_identifier_sequence_number"
Detail: Key (aggregate_id, sequence_number)=(b02a5364-ee34-431a-ab1a-6c59bb937845, 1) already exists.
As you can see the timestamp of the events are nearly the same:
EventA: 2020-11-30T15:14:52.06794746Z
vs. EventB: 2020-11-30T15:14:52.067871723Z
To first answer your question, confiruging a
PropagatingErrorHandler
does not help becauseTrackingEventProcessor
is not going to retry aDeadlineMessage
. It only works for retrying real events which is not the case dor aDeadlineMessage
since it is not an Event.Now to your problem, we are assuming that your Saga has a
DeadlineHandler
and this component is dispatching aCommand
towards yourAggregate
at the same time another component is also dispatching aCommand
to the sameAggregate
. In that way, theAggregate
is failing to handle the secondCommand
. Based on that, we can give you 2 advices:CommandBus
. In short, it will give you the following:RetryScheduler
configured on yourCommandGateway
. You can read more about it here.