Azure Storage Persistence

NuGet Package NServiceBus.Persistence.AzureStorage (2.x)
Target NServiceBus Version: 7.x

Certain features of NServiceBus require persistence to permanently store data. Among them are subscription storage, sagas, and timeouts. Various storage options are available including Azure Storage Services.

Azure Storage Persistence stores NServiceBus data in Azure Table storage.

Persistence at a glance

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

Supported storage typesSagas, Subscriptions, Timeouts
Concurrency controlOptimistic concurrency
Scripted deploymentNot supported
InstallersNone. The required table structure is always created at runtime if required.

Enable Azure Storage Persistence

First add a reference to the assembly that contains the Azure storage persisters, which is done by adding a NuGet package reference to NServiceBus.Persistence.AzureStorage.

var persistence = endpointConfiguration.UsePersistence<AzureStoragePersistence>();

Saga correlation

In Versions 6 and above of NServiceBus, all correlated properties are unique by default so there is no longer a configuration setting.

One of the limitations of the Azure Storage Persistence is support for only one correlation property.

To ensure that only one saga can be created for a given correlation property value, secondary indexes are used. Entities for the secondary index are stored in the same table as a saga. When a saga is completed the secondary index entity is removed as well. It's possible, but highly unlikely, that the saga's completion can leave an orphaned secondary index record. This does not impact the behavior of the persistence as it can detect orphaned records, but may leave a dangling entity in a table with a following WARN entry in logs: Removal of the secondary index entry for the following saga failed: {sagaId}.

If migrating from Version 6.2.3 or below without applying saga deduplication a DuplicatedSagaFoundException can be thrown when when creating secondary index entities. The exception message will include all the information to track down the error for example:

Sagas of type MySaga with the following identifiers 'GUID1', 'GUID2' are considered duplicates because of the violation of the Unique property CorrelationId.

The upgrade guide linked above contains instructions.

Saga concurrency

When simultaneously handling messages, conflicts may occur. See below for examples of the exceptions which are thrown. Saga concurrency explains how these conflicts are handled, and contains guidance for high-load scenarios.

Starting a saga

Example exception:

NServiceBus.Persistence.AzureStorage.RetryNeededException: This operation requires a retry as it wasn't possible to successfully process it now.

Updating or deleting saga data

Azure Storage Persistence uses optimistic concurrency control when updating or deleting saga data.

Example exception:

Microsoft.WindowsAzure.Storage.StorageException: Element 0 in the batch returned an unexpected response code.

Request Information
RequestDate:Tue, 24 Sep 2019 15:16:45 GMT
StatusMessage:The update condition specified in the request was not satisfied.
ErrorMessage:The update condition specified in the request was not satisfied.

Supported saga properties' types

Azure Storage Persistence supports exactly the same set of types as Azure Table Storage. When a saga containing a property of an unsupported type is persisted, an exception containing the following information is thrown: The property type 'the_property_name' is not supported in windows azure table storage. If an object of a non-supported type is required to be stored, then it's a user responsibility to serialize/deserialize the value.

Saga Correlation property restrictions

Saga correlation property values are subject to the underlying Azure Storage table PartitionKey and RowKey restrictions:


Related Articles

Last modified