Getting Started
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Previews
Samples

Transactional Session with RavenDB Persistence

NuGet Package: NServiceBus.RavenDB.TransactionalSession (7.x)
Target Version: NServiceBus 7.x

In order to use the TransactionalSession feature with RavenDB persistence, add a reference to the NServiceBus.RavenDB.TransactionalSession NuGet package.

Configuration

To enable the TransactionalSession feature:

var persistence = config.UsePersistence<RavenDBPersistence>();
persistence.EnableTransactionalSession();

Opening a session

To open a RavenDB transactional session:

using var childBuilder = builder.CreateChildBuilder();
var session = childBuilder.Build<ITransactionalSession>();
await session.Open(new RavenDbOpenSessionOptions())
    .ConfigureAwait(false);

// use the session

await session.Commit()
    .ConfigureAwait(false);

Multi-tenancy support

The specific tenant database name is retrieved from message headers as configured in the SetMessageToDatabaseMappingConvention-method. This header needs to be set in the options so that the necessary information is available when storing operations and interacting with the outbox.

using var childBuilder = builder.CreateChildBuilder();
var session = childBuilder.Build<ITransactionalSession>();
await session.Open(
    new RavenDbOpenSessionOptions(
        new Dictionary<string, string>
        {
                // information is added to the message headers for the
                // `SetMessageToDatabaseMappingConvention`-method
                {"tenantDatabaseName", "tenantA-databaseName"}
        }))
    .ConfigureAwait(false);

// use the session

await session.Commit()
    .ConfigureAwait(false);

Transaction usage

Message and database operations made via the the transactional session are committed together once the session is committed:

await session.Open(new RavenDbOpenSessionOptions())
    .ConfigureAwait(false);

// add messages to the transaction:
await session.Send(new MyMessage())
    .ConfigureAwait(false);

// access the database:
var ravenSession = session.SynchronizedStorageSession.RavenSession();

await session.Commit()
    .ConfigureAwait(false);

See the RavenDB shared session documentation for further details about using the transaction.

In order to guarantee atomic consistency across message and database operations, the Outbox needs to be enabled. Otherwise Commit executes database modifications first and then messages are dispatched with best-effort.

Related Articles


Last modified