3 votes

Transactions avec ASP.NET Identity UserManager

J'essaie de mettre à jour un utilisateur.

AppUserManager appUserManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();

AppUser member = await appUserManager.FindByIdAsync(User.Identity.GetUserId());

member.HasScheduledChanges = true;

IdentityResult identityResult = appUserManager.Update(member);

Si un appel ultérieur à une API Web échoue, je dois annuler toutes les modifications apportées à l'utilisateur. Je connais les transactions, comme celle-ci :

using (var context = HttpContext.GetOwinContext().Get<EFDbContext>())
 {
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {      
        try
        {   
            // Changes

            member.HasScheduledChanges = true;

            // Would this be transactional?
            IdentityResult identityResult = appUserManager.Update(member);               

            context.SaveChanges();

            dbContextTransaction.Commit();
        }
        catch //(Exception ex)
        {

            // dbContextTransaction.Rollback(); no need to call this manually.
        }
    }
}

Mais les opérations effectuées avec AppUserManager à l'intérieur du bloc try seront-elles transactionnelles ? En outre, utilisent-ils la même instance de EFDbContext ? En d'autres termes, je ne sais pas si le contexte var au début du deuxième exemple de code serait utilisé par l'appel de la méthode "Update" de appUserManager dans le bloc try.

De même, AppUserManager est créé comme ceci :

public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
{           

    EFDbContext db = context.Get<EFDbContext>();

    AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db));

    // etc.

    return manager;
}

6voto

trailmax Points 5164

EFDbContext dans vos exemples sont les mêmes - dans les deux cas, vous les résolvez à partir du contexte OWIN, ce n'est donc pas un problème. Cependant, Identity est écrit de manière agnostique par rapport au stockage, ce qui signifie que le mécanisme de stockage peut être remplacé par un serveur autre que SQL Server. Cela implique l'absence de transactions à l'intérieur de AppUserManager . Vous devez donc créer le vôtre.

J'utilise régulièrement var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled) dans mes applications de production (seulement avec un peu plus d'architecture) :

using(var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    try
    {
        AppUserManager appUserManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();

        AppUser member = await appUserManager.FindByIdAsync(User.Identity.GetUserId());

        member.HasScheduledChanges = true;

        IdentityResult identityResult = appUserManager.Update(member);
        scope.Complete();
    }
    catch (Exception ex)
    {
        scope.Dispose();
        throw;
    }
}

4voto

adnan Points 844

La solution complète pour le commit / rollback de transaction en utilisant asp.net identity UserManager

var appDbContext = HttpContext.GetOwinContext().Get<ApplicationDbContext>();
using (var identitydbContextTransaction = appDbContext.Database.BeginTransaction())
{
   try
   {
       var result = await UserManager.CreateAsync(user, "password");
       if (result.Succeeded)
       {
         var userinfo = await UserManager.FindByNameAsync("Email");
         var userId = user.Id;
         await UserManager.AddToRoleAsync(userId, "rolename");

         identitydbContextTransaction.Commit();
       }
  }
  catch (Exception)
  {
        identitydbContextTransaction.Rollback();
  }
}

il peut vous aider, à faire une transaction en utilisant asp.net identity UserManager. mais son travail moi, si toute erreur s'est produite dans la transaction, il sera rollback toutes les transactions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X