dotnet / dotnet/eShop

Shouldn't ResilentTransaction class recreate DbContext on retry?

Open
#161 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
10.9k
Forks
3.8k
Avg merge
1d 11h
Merged PRs (30d)
4

Description

Hello! In the ResilientTransaction class, there is a block with IExecutionStrategy, but DbContext is reused between retries, which can lead to bugs because DbContext doesn't clean its change tracker and event registrations between retries.

Currently, there are no bugs because this class is used only in one place. However, later, if it were to be used extensively, it could lead to some bugs. For example:
```csharp
strategy.ExecuteAsync(
async (context) =>
{
var user = new User(
id: 0,
name: "biba");

context.Add(user);

// If TimeoutException is thrown, IExecutionStrategy will retry
var products = await context.Products.ToListAsync();

await context.SaveChangesAsync();
});
```
When a transient exception occurs, a second user will be added to the context because, as I mentioned, DbContext doesn't change its change tracker between retries.

A better approach would be to recreate the DbContext instance per retry so that we can have a clean change tracker, event registrations, etc. In the [link](https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency) provided inside the ResilientTransaction class, there is a great example of how IExecutionStrategy should be used:
```csharp
using var db = new BloggingContext();
var strategy = db.Database.CreateExecutionStrategy();

strategy.Execute(
() =>
{
using var context = dbContextFactory.CreateDbContext();
using var transaction = context.Database.BeginTransaction();

context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context.SaveChanges();

context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
context.SaveChanges();

transaction.Commit();
});
```

This issue is more of a question than a suggestion. I want to know if my assumptions about DbContext right, or if im wrong and DbContext isn't recreated on purpose

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.