Duplicate key during snapshot

120 views
Skip to first unread message

BA

unread,
Jul 1, 2014, 3:13:13 AM7/1/14
to axonfr...@googlegroups.com
Hi all,

I have changed my configuration to Asynchronous cluster for all my listeners, and now, i have an error during snapshotting when i launch a lot of commands :

com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: contacts.snapshotevents.$aggregateIdentifier_1_type_1_sequenceNumber_1  dup key: { : "1", : "GroupTree", : 16207 }
    at com
.mongodb.CommandResult.getException(CommandResult.java:98)
    at com
.mongodb.CommandResult.throwOnError(CommandResult.java:134)
    at com
.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:142)
    at com
.mongodb.DBTCPConnector.say(DBTCPConnector.java:183)
    at com
.mongodb.DBTCPConnector.say(DBTCPConnector.java:155)
    at com
.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:249)
    at com
.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:205)
    at com
.mongodb.DBCollection.insert(DBCollection.java:57)
    at com
.mongodb.DBCollection.insert(DBCollection.java:100)
    at org
.axonframework.eventstore.mongo.MongoEventStore.appendSnapshotEvent(MongoEventStore.java:194)
    at org
.axonframework.eventsourcing.AbstractSnapshotter$CreateSnapshotTask.run(AbstractSnapshotter.java:101)
    at org
.axonframework.eventsourcing.AbstractSnapshotter$TransactionalRunnableWrapper.run(AbstractSnapshotter.java:173)
    at org
.axonframework.eventsourcing.AbstractSnapshotter$SilentTask.run(AbstractSnapshotter.java:193)
    at java
.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java
.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java
.lang.Thread.run(Thread.java:744)


The error is displaying several times during operation.

My configuration :

    <axon:cluster id="defaultCluster" default="true" />

   
<axon:cluster id="replayingCluster">
       
<axon:replay-config event-store="eventStore" />
       
<axon:selectors>
           
<axon:package prefix="mybasepackage.interfaces.query" />
       
</axon:selectors>
   
</axon:cluster>

   
<axon:cluster id="asyncCluster">
       
<bean class="org.axonframework.eventhandling.async.AsynchronousCluster">
           
<constructor-arg value="asyncCluster" />
           
<constructor-arg ref="asyncExecutor" />
           
<constructor-arg>
               
<bean class="org.axonframework.eventhandling.async.SequentialPerAggregatePolicy" />
           
</constructor-arg>
       
</bean>
       
<axon:selectors>
           
<axon:package prefix="mybasepackage" />
       
</axon:selectors>
   
</axon:cluster>

   
<bean id="asyncExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean">
       
<property name="corePoolSize" value="1" />
       
<property name="waitForTasksToCompleteOnShutdown" value="true" />
   
</bean>

   
<axon:command-bus id="commandBus" />

   
<bean id="commandGateway" class="org.axonframework.commandhandling.gateway.CommandGatewayFactoryBean">
       
<property name="commandBus" ref="commandBus" />
   
</bean>

   
<axon:event-bus id="eventBus" />

   
   
<axon:event-sourcing-repository id="groupTreeRepository" aggregate-type="mybasepackage.group.GroupTree">
       
<axon:snapshotter-trigger event-count-threshold="50" snapshotter-ref="snapshotter" />
   
</axon:event-sourcing-repository>

   [...]

   
<bean id="eventStore" class="org.axonframework.eventstore.mongo.MongoEventStore">
       
<constructor-arg ref="axonMongoTemplate" />
       
<constructor-arg ref="eventSerializer" />
       
<constructor-arg ref="storageStrategy" />
   
</bean>

   
<bean id="storageStrategy" class="org.axonframework.eventstore.mongo.DocumentPerCommitStorageStrategy" />

   
<bean id="snapshotter" class="org.axonframework.eventsourcing.SpringAggregateSnapshotter">
       
<property name="eventStore" ref="eventStore" />
       
<property name="executor" ref="taskExecutor" />
   
</bean>

   
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
       
<property name="corePoolSize" value="2" />
       
<property name="maxPoolSize" value="5" />
       
<property name="waitForTasksToCompleteOnShutdown" value="true" />
   
</bean>



Do you have an idea ?

Best regards,

Baptiste.

bui...@gmail.com

unread,
Jul 1, 2014, 2:45:00 PM7/1/14
to axonfr...@googlegroups.com
Hi,

snapshotting is an asynchronous process. It's possible that two requests for the same snapshot are trigger in short succession. Currently, Axon will process both requests and has a chance to create two snapshots with the same sequence number. That's what generates the duplicate key exception. 

This reminds me that I wanted to include a feature that ignores the creation of a snapshot based on a single event. Will create an issue to track it. 

Cheers,

Allard
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

BA

unread,
Jul 1, 2014, 3:32:35 PM7/1/14
to axonfr...@googlegroups.com
Ok. if i understand this is just warning without consequence, may be my event-count-threshold value is too small.

Allard Buijze

unread,
Jul 2, 2014, 1:29:38 AM7/2/14
to axonfr...@googlegroups.com
Hi,

it can happen with any event-count-threshold. If two commands load the same aggregate is quick succession, it is possible that the second time happens before the snapshot is created, causing the trigger to fire again. 
A snapshotter always creates a snapshot of the current state, not the state as it was when it was triggered. 

Hooe this clarifies it a bit. 
Cheers,

Allard

On 1 jul. 2014, at 21:32, BA <baptist...@gmail.com> wrote:

Ok. if i understand this is just warning without consequence, may be my event-count-threshold value is too small.

--
Reply all
Reply to author
Forward
0 new messages