Outbox with NHibernate persistence

Component: NHibernate Persistence | Nuget: NServiceBus.NHibernate (Version: 7.x)
Target NServiceBus Version: 6.x

The Outbox feature requires persistence in order to store the messages and enable deduplication.

Table

To keep track of duplicate messages, the NHibernate implementation of Outbox requires the creation of OutboxRecord table.

Customizing Outbox record persistence

By default the Outbox records are persisted in the following way:

  • The table has an auto-incremented integer primary key.
  • The MessageId column has a unique index.
  • There are indices on Dispatched and DispatchedAt columns.

Following API can be used to provide a different mapping of Outbox data to the underlying storage:

7.x NServiceBus.NHibernate
Edit
var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.UseOutboxRecord<MyOutboxRecord, MyOutboxRecordMapping>();
7.x NServiceBus.NHibernate
Edit
public class MyOutboxRecord :
    IOutboxRecord
{
    public virtual string MessageId { get; set; }
    public virtual bool Dispatched { get; set; }
    public virtual DateTime? DispatchedAt { get; set; }
    public virtual string TransportOperations { get; set; }
}

public class MyOutboxRecordMapping :
    ClassMapping<MyOutboxRecord>
{
    public MyOutboxRecordMapping()
    {
        Table("MyOutboxTable");
        Id(
            idProperty: record => record.MessageId,
            idMapper: mapper => mapper.Generator(Generators.Assigned));
        Property(
            property: record => record.Dispatched,
            mapping: mapper =>
            {
                mapper.Column(c => c.NotNullable(true));
                mapper.Index("OutboxRecord_Dispatched_Idx");
            });
        Property(
            property: record => record.DispatchedAt,
            mapping: pm => pm.Index("OutboxRecord_DispatchedAt_Idx"));
        Property(
            property: record => record.TransportOperations,
            mapping: mapper => mapper.Type(NHibernateUtil.StringClob));
    }
}

Should custom mapping be required, the following characteristics of the original mapping needs to be preserved:

  • Values stored in MessageId column must be unique and an attempt to insert a duplicate entry must cause an exception.
  • Querying by Dispatched and DispatchedAt columns must be efficient because these columns are used by the cleaner process to remove outdated records.

Deduplication record lifespan

The NHibernate implementation by default keeps deduplication records for 7 days and runs the purge every 1 minute.

These default settings can be changed by specifying new defaults in the config file using TimeStamp strings:

Edit
<appSettings>
  <add key="NServiceBus/Outbox/NHibernate/TimeToKeepDeduplicationData"
       value="7.00:00:00" />
  <add key="NServiceBus/Outbox/NHibernate/FrequencyToRunDeduplicationDataCleanup"
       value="00:01:00" />
</appSettings>

Related Articles

  • Outbox
    Reliable messaging without distributed transactions.

Last modified