Search code examples
.net-coreef-core-2.1usermanager

Using ExecuteInTransaction with UserManager


We are implementing EnableRetryOnFailure but as discussed on https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency, this does not work out of the box for user defined transactions.

One of the recommendations from the above link (options 3 & 4) is to use an ExecutionStrategy.ExecuteInTransaction, and to call SaveChanges with acceptAllChangesOnSuccess: false.

This is necessary so that the transaction can be retried if SaveChanges succeeds but the transaction fails.

The issue we are having is that we have UserManager methods wrapped up inside our transactions, and these will internally be calling SaveChanges on the context.

How can we do this, when we cannot change UserManager to use acceptAllChangesOnSuccess: false?


Solution

  • Adding a user with the UserManager.CreateAsync method will call the SaveChanges method on the internal UserStore. The UserStore class has a public property, AutoSaveChanges, that indicates whether to call the SaveChanges method. By setting the AutoSaveChanges property to false and then calling the UserManager.CreateAsync method, the SaveChanges method will not be called.

    https://github.com/dotnet/aspnetcore/blob/839cf8925278018903f53f22d580d15b0a59ca0f/src/Identity/EntityFrameworkCore/src/UserStore.cs#L141

    1. set false to UserStore.AutoSaveChanges property.
    2. userManager.CreateAsync(user) (no call SaveChanges)
    3. context.SaveChanges(acceptAllChangesOnSuccess: false)