Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

NHibernate Persistence

NuGet Package: NServiceBus.NHibernate (8.x - 8.3)
Target Version: NServiceBus 7.x

Uses the NHibernate ORM for persistence.

Persistence at a glance

For a description of each feature, see the persistence at a glance legend.

Feature
Supported storage typesSagas, Outbox, Subscriptions, Timeouts
TransactionsLocal database transactions or distributed transactions when available
Concurrency controlOptimistic concurrency for correctness + pessimistic concurrency for performance
Scripted deploymentNot supported
InstallersTable structure is created by installers.

Supported database engines

Usage

The next stage is to tell NServiceBus how to use NHibernate for persistence

// Use NHibernate for all persistence concerns
endpointConfiguration.UsePersistence<NHibernatePersistence>();

// or select specific concerns
endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Sagas>();
endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Subscriptions>();
endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Timeouts>();
endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Outbox>();

Connection strings

It is possible to pass a connection string in the app.config file, as described in the using configuration convention section.

With code

NHibernate persistence requires specifying a connection string.

The connection string might be passed using code configuration:

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.ConnectionString(@"Data Source=.\SqlExpress;Database=nservicebus");

Customizing the configuration

To customize the NHibernate Configuration object used to bootstrap the persistence mechanism, either provide a ready-made object via code or use convention-based XML configuration. The code-based approach overrides the configuration-based one when both are used.

Passing configuration in code

To specify configuration on a per-concern basis:

var nhConfiguration = new Configuration
{
    Properties =
    {
        ["dialect"] = "NHibernate.Dialect.MsSql2008Dialect"
    }
};

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.UseSubscriptionStorageConfiguration(nhConfiguration);
persistence.UseTimeoutStorageConfiguration(nhConfiguration);

To use a given NHibernate Configuration object for all the persistence concerns:

var nhConfiguration = new Configuration
{
    Properties =
    {
        ["dialect"] = "NHibernate.Dialect.MsSql2008Dialect",
        ["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider",
        ["connection.driver_class"] = "NHibernate.Driver.Sql2008ClientDriver"
    }
};

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.UseConfiguration(nhConfiguration);
var nhConfiguration = new Configuration
{
    Properties =
    {
        ["dialect"] = "NHibernate.Dialect.MsSql2008Dialect"
    }
};

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Subscriptions>();
persistence.UseConfiguration(nhConfiguration);

Using configuration convention

NServiceBus picks up the connection setting from the app.config from connectionStrings and appSettings sections. The convention used for appSettings does not support defining settings specific for a single persistence concern. If this level of granularity is required, use a code-based approach.

<configuration>
  <connectionStrings>
    <add name="NServiceBus/Persistence"
         connectionString="Data Source=.\SqlExpress;Initial Catalog=nservicebus"/>
    <!--Following connection string will be used only for accessing Saga data-->
    <add name="NServiceBus/Persistence/NHibernate/Saga"
         connectionString="Data Source=.\SqlExpress;Initial Catalog=nservicebus_saga"/>
  </connectionStrings>

  <!-- specify the other needed NHibernate settings like below in appSettings:-->
  <appSettings>
    <!-- dialect is defaulted to MsSql2008Dialect, if needed change accordingly -->
    <add key="NServiceBus/Persistence/NHibernate/dialect"
         value="NHibernate.Dialect.MsSql2008Dialect" />
    <!-- other optional settings examples -->
    <add key="NServiceBus/Persistence/NHibernate/connection.provider"
         value="NHibernate.Connection.DriverConnectionProvider" />
    <add key="NServiceBus/Persistence/NHibernate/connection.driver_class"
         value="NHibernate.Driver.Sql2008ClientDriver" />
  </appSettings>
</configuration>

Change database schema

The database schema can be changed by defining the default_schema NHibernate property. See the previous Customizing the configuration section.

Subscription caching

The subscriptions can be cached when using NHibernate. This can improve the performance of publishing events as it is not required to request matching subscriptions from storage.

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Subscriptions>();
persistence.EnableCachingForSubscriptionStorage(TimeSpan.FromMinutes(1));

Controlling schema

In some cases it may be necessary to take full control over creating the SQL structure used by the NHibernate persister. In these cases the automatic creation of SQL structures on install can be disabled as follows:

For all persistence schema updates:

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.DisableSchemaUpdate();

For subscription schema update:

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.DisableSubscriptionStorageSchemaUpdate();

For timeout schema update:

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.DisableTimeoutStorageSchemaUpdate();

Generating scripts for deployment

To create scripts for execution in production without using the installers, run an install in a lower environment and then export the SQL structure. This structure can then be migrated to production.

Samples

Related Articles