﻿# Transactional Session with CosmosDB Persistence

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


In order to use the [transactional session feature](/nservicebus/transactional-session/index.md) with CosmosDB Persistence, add a reference to the `NServiceBus.Persistence.CosmosDB.TransactionalSession` NuGet package.

## Configuration

To enable the transactional session feature:

<!-- snippet: enabling-transactional-session-cosmos -->

```cs
var persistence = config.UsePersistence<CosmosPersistence>();
persistence.EnableTransactionalSession();
```

<!-- endsnippet -->

## Opening a session

To open a CosmosDB transactional session, a partition key must be provided:

<!-- snippet: open-transactional-session-cosmos -->

```cs
using var childScope = serviceProvider.CreateScope();
var session = childScope.ServiceProvider.GetService<ITransactionalSession>();
await session.Open(
        new CosmosOpenSessionOptions(
            new PartitionKey("MyPartitionKey")));

// use the session

await session.Commit();
```

<!-- endsnippet -->

### Custom container

By default, the transactional session uses the [configured default container](/persistence/cosmosdb/index.md#usage-customizing-the-container-used). The `CosmosOpenSessionOptions` instance can be configured with container information to be used for this transaction:

<!-- snippet: open-transactional-session-cosmos-container -->

```cs
using var childScope = serviceProvider.CreateScope();
var session = childScope.ServiceProvider.GetService<ITransactionalSession>();
await session.Open(
        new CosmosOpenSessionOptions(
            new PartitionKey("MyPartitionKey"),
            new ContainerInformation(
                "MyContainer",
                new PartitionKeyPath("/path/to/partition/key"))));

// use the session

await session.Commit();
```

<!-- endsnippet -->

## Transaction usage

Message and database operations made via the transactional session are committed together once the session is committed:

<!-- snippet: use-transactional-session-cosmos -->

```cs
await session.Open(
        new CosmosOpenSessionOptions(
            new PartitionKey("MyPartitionKey")));

// add messages to the transaction:
await session.Send(new MyMessage());

// access the database:
var cosmosSession = session.SynchronizedStorageSession.CosmosPersistenceSession();

await session.Commit();
```

<!-- endsnippet -->

See the [Cosmos DB persistence transactions documentation](/persistence/cosmosdb/transactions.md#sharing-the-transaction) for further details about using the transaction.

> [!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.
