Marten Configuration
Marten is an open source library that provides provides .NET developers with the ability to easily use the proven PostgreSQL database engine and its
fantastic JSON support as a fully fledged document database. To use Marten and PostgreSQL as saga persistence, you need to install MassTransit.Marten
NuGet package and add some code.
MassTransit will automatically configure the CorrelationId property so that Marten will use that property as the primary key. No attribute is necessary.
public class OrderState : SagaStateMachineInstance{ public Guid CorrelationId { get; set; } public string CurrentState { get; set; }
public DateTime? OrderDate { get; set; }}Configure the saga repository
Section titled “Configure the saga repository”To configure Marten and use it as a saga repository with MassTransit, use the MartenRepository method when adding the saga.
services.AddMarten(options =>{ const string connectionString = "host=localhost;port=5432;database=orders;username=web;password=webpw;";
options.Connection(connectionString);});
services.AddMassTransit(x =>{ x.AddSagaStateMachine<OrderStateMachine, OrderState>() .MartenRepository();});Set the saga repository provider
Section titled “Set the saga repository provider”When adding sagas using any of the AddSagas or AddSagaStateMachines methods, the Marten saga repository provider can be used to automatically configure
Marten as the saga repository.
services.AddMarten(options =>{ const string connectionString = "host=localhost;port=5432;database=orders;username=web;password=webpw;";
options.Connection(connectionString);});
services.AddMassTransit(x =>{ x.SetMartenSagaRepositoryProvider();
var entryAssembly = System.Reflection.Assembly.GetEntryAssembly();
x.AddSagaStateMachines(entryAssembly);});To configure the saga repository for a specific saga type, use the AddSagaRepository method and specify the appropriate saga repository.
services.AddMassTransit(x =>{ x.SetMartenSagaRepositoryProvider();
var entryAssembly = System.Reflection.Assembly.GetEntryAssembly();
x.AddSagaStateMachines(entryAssembly);
x.AddSagaRepository<OrderState>() .MartenRepository();});Optimistic Concurrency
Section titled “Optimistic Concurrency”To use Marten’s built-in optimistic concurrency, which uses an eTag-like version metadata field, an additional schema configuration may be specified.
This does not require any additional fields in the saga class.
services.AddMassTransit(x =>{ x.AddSagaStateMachine<OrderStateMachine, OrderState>() .MartenRepository(r => r.UseOptimisticConcurrency(true));});Alternatively, you can add the UseOptimisticConcurrency attribute to the saga class.
[UseOptimisticConcurrency]public class OrderState : SagaStateMachineInstance{ public Guid CorrelationId { get; set; } // ...}Index Creation
Section titled “Index Creation”Marten can create indices for properties, which greatly increases query performance. If your saga is correlating events using other saga properties, index creation is recommended. For example, if an OrderNumber property was added to the OrderState class, it could be indexed by configuring it in the repository.
public class OrderState : SagaStateMachineInstance{ public Guid CorrelationId { get; set; } public string CurrentState { get; set; }
public string OrderNumber { get; set; }
public DateTime? OrderDate { get; set; }}services.AddMarten(options =>{ const string connectionString = "host=localhost;port=5432;database=orders;username=web;password=webpw;";
options.Connection(connectionString);});
services.AddMassTransit(x =>{ x.AddSagaStateMachine<OrderStateMachine, OrderState>() .MartenRepository(r => r.Index(x => x.OrderNumber));});Details on how Marten creates indices is available in the Indexing documentation.