﻿# Transactional Session with RavenDB Persistence

<!-- Version variant: ravents_10; default: [/nservicebus/transactional-session/persistences/ravendb.md](/nservicebus/transactional-session/persistences/ravendb.md) -->


To use the [transactional session feature](/nservicebus/transactional-session/index.md) with RavenDB persistence, add a reference to the `NServiceBus.RavenDB.TransactionalSession` NuGet package.

## Configuration

To enable the transactional session feature:

<!-- snippet: enabling-transactional-session-ravendb -->

```cs
var persistence = config.UsePersistence<RavenDBPersistence>();
persistence.EnableTransactionalSession();
```

<!-- endsnippet -->

## Opening a session

To open a RavenDB transactional session:

<!-- snippet: open-transactional-session-ravendb -->

```cs
using var childScope = serviceProvider.CreateScope();
var session = childScope.ServiceProvider.GetService<ITransactionalSession>();
await session.Open(new RavenDbOpenSessionOptions());

// use the session

await session.Commit();
```

<!-- endsnippet -->

### Multi-tenancy support

The specific tenant database name is retrieved from message headers as configured in the [`SetMessageToDatabaseMappingConvention`-method](/persistence/ravendb/index.md#multi-tenant-support).
This header needs to be set in the options to make the necessary information available when storing operations and interacting with the outbox.

<!-- snippet: open-transactional-session-ravendb-multitenant -->

```cs
using var childScope = serviceProvider.CreateScope();
var session = childScope.ServiceProvider.GetService<ITransactionalSession>();
await session.Open(
    new RavenDbOpenSessionOptions(
        new Dictionary<string, string>
        {
                // information is added to the message headers for the `SetMessageToDatabaseMappingConvention`-method
                {"tenantDatabaseName", "tenantA-databaseName"}
        }));

// use the session

await session.Commit();
```

<!-- endsnippet -->

## Transactions usage

Message and database operations made via the transactional session are committed together once the session is committed:

<!-- snippet: use-transactional-session-raven -->

```cs
await session.Open(new RavenDbOpenSessionOptions());

// add messages to the transaction:
await session.Send(new MyMessage());

// access the database:
var ravenSession = session.SynchronizedStorageSession.RavenSession();

await session.Commit();
```

<!-- endsnippet -->

For further details about using the transaction, see the [RavenDB shared session documentation](/persistence/ravendb/index.md#shared-session).

> [!WARNING]
> In order to guarantee atomic consistency across message and database operations, the [outbox](/nservicebus/outbox/index.md) must be enabled. Otherwise `Commit` executes database modifications first and then messages are dispatched with best-effort.
