eShop icon indicating copy to clipboard operation
eShop copied to clipboard

Shouldn't ResilentTransaction class recreate DbContext on retry?

Open NotIlya4 opened this issue 1 year ago • 0 comments

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:

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 provided inside the ResilientTransaction class, there is a great example of how IExecutionStrategy should be used:

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

NotIlya4 avatar Jan 22 '24 16:01 NotIlya4