In order to use the transactional session feature with SQL Persistence, add a reference to the NServiceBus.
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 childBuilder = builder.CreateChildBuilder();
var session = childBuilder.Build<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 childBuilder = builder.CreateChildBuilder();
var session = childBuilder.Build<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.
Commit
executes database modifications first and then messages are dispatched with best-effort.