RavenDB Persistence Upgrade from 3 to 4

Component: RavenDB Persistence
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.

As part of this update NServiceBus Version 6 will be required.

Namespace changes

Namespaces for public types have been consolidated to make customizations more discoverable. The primary namespaces are NServiceBus for customization options that need to be discoverable, and NServiceBus.Persistence.RavenDB for advanced APIs. A single using NServiceBus directive should be sufficient to find all necessary options.

As part of this move, the following classes were moved to different namespaces:

  • NServiceBus.Persistence.RavenDBPersistence to the NServiceBus namespace.
  • NServiceBus.RavenDB.Outbox.RavenDBOutboxExtensions to the NServiceBus namespace.
  • NServiceBus.RavenDB.ConnectionParameters to the NServiceBus.Persistence.RavenDB namespace.

Use of RavenDB Async API

NServiceBus now uses the asynchronous RavenDB API for all operations. If sharing the session between NServiceBus and handler code is required, then handler code will need to be adjusted to utilize the asynchronous RavenDB API as well.

Previously the API exposed an IDocumentSession, but now exposes IAsyncDocumentSession instead, which contains the same operations but using a Task-based API.

Configuring a shared session

Configuring a shared raven session now requires a Func<IAsyncDocumentSession> instead of a Func<IDocumentSession>.

4.x NServiceBus.RavenDB
Func<IAsyncDocumentSession> sessionFactory = () => someAsyncSession;

var persistence = endpointConfiguration.UsePersistence<RavenDBPersistence>();
persistence.UseSharedAsyncSession(sessionFactory);
3.x NServiceBus.RavenDB
Func<IDocumentSession> sessionFactory = () => someSession;

var persistence = busConfiguration.UsePersistence<RavenDBPersistence>();
persistence.UseSharedSession(sessionFactory);

ISessionProvider is obsolete

In Version 3 of NServiceBus.RavenDB an ISessionProvider was available for dependency injection. The new method of accessing the raven session is the SynchronizedStorageSession.

4.x NServiceBus.RavenDB
public class HandlerWithRavenSession :
    IHandleMessages<MyMessage>
{
    public Task Handle(MyMessage message, IMessageHandlerContext context)
    {
        var ravenSession = context.SynchronizedStorageSession
            .RavenSession();
        return SomeLibrary.SomeAsyncMethod(message, ravenSession);
    }
}
3.x NServiceBus.RavenDB
public class HandlerWithRavenSession :
    IHandleMessages<MyMessage>
{
    ISessionProvider sessionProvider;

    public HandlerWithRavenSession(ISessionProvider sessionProvider)
    {
        this.sessionProvider = sessionProvider;
    }

    public void Handle(MyMessage message)
    {
        var ravenSession = sessionProvider.Session;
        SomeLibrary.SomeMethod(message, ravenSession);
    }
}

Session is available regardless of features enabled

In Version 3, the RavenStorageSession was only registered if at least one out of Outbox and Sagas were enabled. There are possible use cases for using the NServiceBus wrapped RavenDB session so the prerequisites have been removed.

Related Articles


Last modified