RavenDB Persistence Saga concurrency

RavenDB's implementation of distributed transactions contains a bug that could cause an endpoint, in certain (rare) conditions, to lose data. If RavenDB is configured to enlist in distributed transactions, read DTC not supported for RavenDB Persistence.

RavenDB honors concurrency semantics in the following way.

Concurrent access to non-existing saga instances

RavenDB lacks support for unique indexes, so the persister mimics this by creating a separate document for each saga to serve this purpose. The key of this document is set to the value of the correlation property, this causes RavenDB to throw a exception should two documents with the same correlation value be created at the same time.

Concurrent access to existing saga instances

The persister makes use of RavenDB optimistic locking causing concurrency exceptions to be throw should the same saga instance be updated concurrently.

This means that the relevant Handle method on the saga will be invoked, even though the message might be later rolled back. Hence it is important to ensure not to perform any work in saga handlers that can't roll back together with the message. This also means that should there be high levels of concurrency there will be N-1 rollbacks where N is the number of concurrent messages. This can cause throughput issues and might require design changes.

Related Articles

  • Saga Concurrency
    NServiceBus gives ACID semantics, using underlying storage so only one worker thread hitting a saga instance can commit.

Last modified