Getting Started
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Previews
Samples

Transactional Session with SQL Persistence

NuGet Package: NServiceBus.Persistence.Sql.TransactionalSession (7.x)

In order to use the transactional session feature with SQL Persistence, add a reference to the NServiceBus.Persistence.Sql.TransactionalSession NuGet package.

Configuration

To enable the transactional session feature:

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

Opening a session

To open a SQL Persistence transactional session:

using var childScope = serviceProvider.CreateScope();
var session = childScope.ServiceProvider.GetService<ITransactionalSession>();
await session.Open(new SqlPersistenceOpenSessionOptions())
    .ConfigureAwait(false);

// use the session

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

Multi-tenancy support

The specific tenant id that is used to construct the connection string is retrieved from message headers as configured in the MultiTenantConnectionBuilder-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 childScope = serviceProvider.CreateScope();
var session = childScope.ServiceProvider.GetService<ITransactionalSession>();
await session.Open(
        new SqlPersistenceOpenSessionOptions((
                     "MyTenantIdHeader", // Name of the header configured in this endpoint to carry the tenant ID
                     "TenantA"))) // The value of the tenant ID header
    .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 SqlPersistenceOpenSessionOptions())
    .ConfigureAwait(false);

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

// access the database:
var sqlSession = session.SynchronizedStorageSession.SqlPersistenceSession();

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

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

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

Related Articles

  • SQL Persistence
    A persister that targets relational databases, including SQL Server, Oracle. MySQL, and PostgreSQL.
  • Transactional session
    Atomicity when modifying data and sending messages outside the context of a message handler.

Last modified