Skip to content

Retryable transactions - #2098

Merged
bkoelman merged 2 commits into
masterfrom
retryable-transactions
Oct 8, 2026
Merged

bkoelman merged 2 commits into
masterfrom
retryable-transactions

Conversation

@bkoelman

@bkoelman bkoelman commented Oct 8, 2026

Copy link
Copy Markdown
Member

This PR adds support for retryable transactions in atomic:operations requests. Retryable transactions are enabled by default in Aspire projects.

You can enable them in regular projects via EF Core options, for example:

builder.Services.AddDbContext<AppDbContext>(options =>
    // Choose one of the following, depending on your database provider.
    options.UseNpgsql(connectionString, optionsBuilder => optionsBuilder.EnableRetryOnFailure())
    options.UseMySql(connectionString, serverVersion, optionsBuilder => optionsBuilder.EnableRetryOnFailure())
    options.UseSqlServer(connectionString, sqlServerOptions => sqlServerOptions.EnableRetryOnFailure())
);

Before this PR, operations requests would fail with:

JsonApiDotNetCore.Errors.FailedOperationException: Exception of type 'JsonApiDotNetCore.Errors.FailedOperationException' was thrown.
---> JsonApiDotNetCore.Repositories.DataStoreUpdateException: Failed to persist changes in the underlying data store.
---> System.InvalidOperationException: The configured execution strategy 'NpgsqlRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit.

Bugfix in this PR: When commit fails, the error source pointer was set to the last operation; it is now set to the list of operations.

To support this feature, the following breaking change to the public API surface was made:

public interface IOperationsTransactionFactory
{
-    Task<IOperationsTransaction> BeginTransactionAsync(CancellationToken cancellationToken);
+    Task<TResult> RunInTransactionAsync<TResult>(Func<IOperationsTransaction, Task<TResult>> asyncAction, CancellationToken cancellationToken);
}

The new method takes a callback where the retryable logic runs. DapperExample was updated for the new interface, but does not support retries. A compatible version of JsonApiDotNetCore.MongoDb will follow soon after this is released.

Closes #2095.

QUALITY CHECKLIST

@bkoelman bkoelman added breaking-change enhancement New feature or improvement labels Oct 8, 2026
@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.53731% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.14%. Comparing base (90de33b) to head (91d022e).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...DotNetCore/AtomicOperations/OperationsProcessor.cs 90.32% 0 Missing and 3 partials ⚠️
...perations/EntityFrameworkCoreTransactionFactory.cs 85.71% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2098   +/-   ##
=======================================
  Coverage   92.14%   92.14%           
=======================================
  Files         366      366           
  Lines       12079    12124   +45     
  Branches     2032     2038    +6     
=======================================
+ Hits        11130    11172   +42     
+ Misses        585      584    -1     
- Partials      364      368    +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bkoelman
bkoelman marked this pull request as ready for review October 8, 2026 23:18
@bkoelman
bkoelman merged commit 4f787d3 into master Oct 8, 2026
15 checks passed
@bkoelman
bkoelman deleted the retryable-transactions branch October 8, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change enhancement New feature or improvement

Development

Successfully merging this pull request may close these issues.

Support retryable transactions (atomic operations)

1 participant