At the moment we’re developing a proof of concept using Axon. For this proof of concept we’re using the FileSystemEventStore as our event store implementation. We’ve had some unexpected behavior with regards to the case sensitivity of the underlying file system.
The problem is that opening the event store file is done using the aggregate identifier which is provided by the command. This identifier could be in a different case than the identifier in the command which created the aggregate. The event store file name is created with the case of the identifier in the command which created the aggregate. This in and of itself wouldn’t have been a problem as it would have led to case sensitive file systems not allowing duplicate names in different cases while case insensitive file systems would have allowed this. Although this would’ve caused different behavior on different platforms it would have been predictable behavior.
Problems arise because of the LockingRepository and the PessimisticLockManager. The locks of the PessimisticLockManager aren’t case insensitive on systems with case insensitive file systems. When saving an aggregate in the LockingRepository, the lock is validated with its LockManager. Because the lock validation is done using the aggregate identifier from the event store (which is possibly in a different case from the identifier in the command which is currently being handled) the lock isn’t considered valid and a ConcurrencyException is thrown.
This ConcurrencyException really threw me for a loop. This might be a tough issue to solve, especially for a component (FileSystemEventStore) which I assume isn’t being used in production. If this isn’t going to be solved, I would suggest adding a little disclaimer to the documentation so other developers might not be as baffled as I was with the ConcurrencyException. If there is an obvious solution to this I would be interested in it.