ConstraintViolationException while trying to apply 2 events on the same Aggregate Root

Hi,

Following is our usecase
a) there are 2 saga handlers listening for 2 seperate events
b) both these saga fire 2 different commands on the same Aggregate Root

At this point looks like one of command handler gets a stale copy of the Aggregate Root and eventually ends up throwing SQLIntegrityConstraintViolationException when trying to apply the event as the other command handler has already applied the event with a new sequence number in Domain entry table

We are using MariaDB database and Axon 2.4.6

As suggested in one of the thread, we also tried changing the isolation level to “READ_COMMITTED” in the hibernate properties of our conn pool but no luck …

Any help is appreciated

Following is the exception that we are getting

`

OUT org.axonframework.repository.ConcurrencyException: Concurrent modification detected for Aggregate identifier [CWN8GPH8], sequence: [2]
at org.axonframework.eventstore.jpa.JpaEventStore.appendEvents(JpaEventStore.java:171) ~[axon-core-…

Caused by: java.sql.BatchUpdateException: Duplicate entry ‘CWN8GPH8-2-PersonAggregateRoot’ for key ‘PRIMARY’
2017-08-05T11:59:12.84+0530 [App/0] OUT Query is: insert into DomainEventEntry (eventIdentifier, payloadRevision, payloadType, timeStamp, metaData, payload, aggregateIdentifier, sequenceNumber, type) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
2017-08-05T11:59:12.84+0530 [App/0] OUT Query is:
2017-08-05T11:59:12.84+0530 [App/0] OUT insert into DomainEventEntry (eventIdentifier, payloadRevision, payloadType, timeStamp, metaData, payload, aggregateIdentifier, sequenceNumber, type) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
at org.mariadb.jdbc.MariaDbServerPreparedStatement.executeInternal(MariaDbServerPreparedStatement.java:378) ~[mariadb-java-client-1.4.0.jar!/:na]
at org.mariadb.jdbc.MariaDbServerPreparedStatement.execute(MariaDbServerPreparedStatement.java:342) ~[mariadb-java-client-1.4.0.jar!/:na]

`

Hi Srinath,

this really sounds like an isolation level issue. Beware that certain thread pools allow you to set an isolation level, which is not used to set the isolation level on the underlying connections, but to return an isolation level to anyone who requests, without requiring to claim a connector for it. In other words, the setting doesn’t really change anything.

Other causes of this issue could be:

  • running on multiple nodes and commands aren’t consistently routed according to their aggregateId
  • you have configured a (custom) LockManager that doesn’t use pessimistic locking

The last two are easier to check. If those are not the case, my bet is on the read_committed part.

Cheers,

Allard