Cortex.Mediator.Behaviors.Transactional 3.1.2

dotnet add package Cortex.Mediator.Behaviors.Transactional --version 3.1.2
                    
NuGet\Install-Package Cortex.Mediator.Behaviors.Transactional -Version 3.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cortex.Mediator.Behaviors.Transactional" Version="3.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cortex.Mediator.Behaviors.Transactional" Version="3.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Cortex.Mediator.Behaviors.Transactional" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cortex.Mediator.Behaviors.Transactional --version 3.1.2
                    
#r "nuget: Cortex.Mediator.Behaviors.Transactional, 3.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cortex.Mediator.Behaviors.Transactional@3.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cortex.Mediator.Behaviors.Transactional&version=3.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Cortex.Mediator.Behaviors.Transactional&version=3.1.2
                    
Install as a Cake Tool

Cortex.Mediator.Behaviors.Transactional ??

Cortex.Mediator.Behaviors.Transactional provides transactional pipeline behaviors for Cortex.Mediator, enabling automatic transaction management for command execution with commit on success and rollback on failure.

Built as part of the Cortex Data Framework, this library ensures data consistency by wrapping command handlers in transactions.

  • ? Automatic Transaction Management
  • ? Async/Await Support with TransactionScope
  • ? Custom Transaction Contexts (EF Core, Dapper, etc.)
  • ? Configurable Isolation Levels & Timeouts
  • ? Selective Command Exclusion

GitHub License NuGet Version GitHub contributors Discord Shield

?? Getting Started

Install via NuGet

dotnet add package Cortex.Mediator.Behaviors.Transactional

??? Setup

In Program.cs or Startup.cs:

using Cortex.Mediator.DependencyInjection;
using Cortex.Mediator.Behaviors.Transactional.DependencyInjection;

// Add mediator with transactional behaviors
builder.Services.AddCortexMediator(
    new[] { typeof(Program) },
    options => options.AddTransactionalBehaviors()
);

// Register transactional options (with defaults)
builder.Services.AddTransactionalBehavior();

With Custom Options

builder.Services.AddTransactionalBehavior(options =>
{
    options.IsolationLevel = IsolationLevel.Serializable;
    options.Timeout = TimeSpan.FromMinutes(2);
    options.ScopeOption = TransactionScopeOption.RequiresNew;
});

?? How It Works

Once configured, all commands automatically execute within a transaction:

public class CreateOrderCommandHandler : ICommandHandler<CreateOrderCommand, OrderResult>
{
    private readonly IOrderRepository _orderRepository;
    private readonly IInventoryService _inventoryService;

    public async Task<OrderResult> Handle(CreateOrderCommand command, CancellationToken ct)
    {
        // All operations are wrapped in a transaction
        var order = await _orderRepository.CreateAsync(command);
        await _inventoryService.ReserveItemsAsync(command.Items);
        
        // ? Auto-commit on success
        // ? Auto-rollback if any exception is thrown
        return new OrderResult { OrderId = order.Id };
    }
}

?? Excluding Commands from Transactions

Using the [NonTransactional] Attribute

[NonTransactional]
public class GetProductsQuery : ICommand<IEnumerable<Product>>
{
    public string SearchTerm { get; set; }
}

Using Configuration

builder.Services.AddTransactionalBehavior(options =>
{
    // Exclude specific command types
    options.ExcludeCommand<ReadOnlyQuery>();
    
    // Or exclude multiple at once
    options.ExcludeCommands(
        typeof(GetProductsQuery),
        typeof(CacheRefreshCommand),
        typeof(LoggingCommand)
    );
});

?? Custom Transaction Context

For more control over transaction management (e.g., with Entity Framework Core):

1. Implement ITransactionalContext

public class EfCoreTransactionalContext : ITransactionalContext
{
    private readonly ApplicationDbContext _context;
    private IDbContextTransaction _transaction;

    public EfCoreTransactionalContext(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task BeginTransactionAsync(CancellationToken ct = default)
    {
        _transaction = await _context.Database.BeginTransactionAsync(ct);
    }

    public async Task CommitAsync(CancellationToken ct = default)
    {
        await _context.SaveChangesAsync(ct);
        await _transaction.CommitAsync(ct);
    }

    public async Task RollbackAsync(CancellationToken ct = default)
    {
        await _transaction.RollbackAsync(ct);
    }
}

2. Register the Custom Context

builder.Services.AddTransactionalBehavior();
builder.Services.AddTransactionalContext<EfCoreTransactionalContext>();

?? Configuration Options

Option Default Description
IsolationLevel ReadCommitted Transaction isolation level
Timeout 30 seconds Transaction timeout duration
ScopeOption Required Transaction scope behavior
AsyncFlowOption Enabled Enables async flow for TransactionScope
ExcludedCommandTypes Empty Commands to exclude from transactions

Isolation Levels

options.IsolationLevel = IsolationLevel.ReadCommitted;     // Default - good for most scenarios
options.IsolationLevel = IsolationLevel.Serializable;      // Strictest - for financial transactions
options.IsolationLevel = IsolationLevel.ReadUncommitted;   // Fastest - allows dirty reads
options.IsolationLevel = IsolationLevel.RepeatableRead;    // Prevents non-repeatable reads
options.IsolationLevel = IsolationLevel.Snapshot;          // Optimistic concurrency

Transaction Scope Options

options.ScopeOption = TransactionScopeOption.Required;     // Join existing or create new (default)
options.ScopeOption = TransactionScopeOption.RequiresNew;  // Always create a new transaction
options.ScopeOption = TransactionScopeOption.Suppress;     // Execute without a transaction

?? Pipeline Behavior Order

When using multiple pipeline behaviors, consider the registration order:

builder.Services.AddCortexMediator(
    new[] { typeof(Program) },
    options =>
    {
        // 1. Validation first (fail fast before transaction starts)
        options.AddFluentValidationBehaviors();
        
        // 2. Transaction wraps the actual execution
        options.AddTransactionalBehaviors();
        
        // 3. Logging (optional)
        options.AddDefaultBehaviors();
    }
);

?? Best Practices

? Keep Transactions Short

// Good: Only database operations
public async Task<Result> Handle(Command command, CancellationToken ct)
{
    await _repository.SaveAsync(entity);
    return Result.Success();
}

// Avoid: External calls inside transactions
public async Task<Result> Handle(Command command, CancellationToken ct)
{
    await _repository.SaveAsync(entity);
    await _emailService.SendAsync(email);  // ? External service call
    return Result.Success();
}

? Exclude Read-Only Operations

[NonTransactional]
public class GetUserByIdQuery : ICommand<UserDto>
{
    public int UserId { get; set; }
}

? Use Appropriate Isolation Levels

// High-throughput reads
options.IsolationLevel = IsolationLevel.ReadCommitted;

// Financial transactions
options.IsolationLevel = IsolationLevel.Serializable;

? Set Appropriate Timeouts

// Quick operations
options.Timeout = TimeSpan.FromSeconds(15);

// Complex batch operations
options.Timeout = TimeSpan.FromMinutes(5);

?? Documentation

For complete documentation, see the WIKI.md file.

?? Contributing

We welcome contributions! See the main Cortex repository for contribution guidelines.

?? License

This project is licensed under the MIT License.

?? Contact


Built with ?? by the Buildersoft team.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.1.2 89 2/10/2026
3.1.1 158 1/30/2026
3.1.0 84 1/30/2026

Initial release of Cortex.Mediator.Behaviors.Transactional - Provides transactional pipeline behaviors for atomic command execution.