For the complete documentation index, see llms.txt. This section of documentation is indexed by https://docs.particular.net/persistence/llms.txt. Here is the markdown version of this page. Markdown versions of documentation pages are available by appending .md to the page URL. Directory URLs use index.md.

SQL Persistence saga concurrency

Component:
Sql Persistence

Default behavior

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

Starting a saga

Example exception:

System.Exception: Failed to ExecuteNonQuery. CommandText:

insert into [dbo].[Samples_SimpleSaga_OrderSaga]
(
    Id,
    Metadata,
    Data,
    PersistenceVersion,
    SagaTypeVersion,
    Concurrency,
    Correlation_OrderId
)
values
(
    @Id,
    @Metadata,
    @Data,
    @PersistenceVersion,
    @SagaTypeVersion,
    1,
    @CorrelationId
) ---> System.Data.SqlClient.SqlException: Cannot insert duplicate key row in object 'dbo.Samples_SimpleSaga_OrderSaga' with unique index 'Index_Correlation_OrderId'. The duplicate key value is (7402c6a7-00bc-40a4-bde2-6e32ec13a7c2).

Updating or deleting saga data

Starting in version 4.1.1, conflicts cannot occur because the persistence uses pessimistic locking. Pessimistic locking is achieved by performing a SELECT ... FOR UPDATE or its dialect-specific equivalent.

Up to and including version 4.1.0, SQL persistence uses optimistic concurrency control when updating or deleting saga data.

Example exception:

System.Exception: Optimistic concurrency violation when trying to complete saga OrderSaga 699d0b1a-e2bf-49fd-8f26-aadf01009eaf. Expected version 4.

Related Articles

  • Saga concurrency
    NServiceBus ensures consistency between saga state and messaging.