与 ASP.NET Identity UserManager 的交易
Transactions with ASP.NET Identity UserManager
我正在尝试更新用户。
AppUserManager appUserManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
AppUser member = await appUserManager.FindByIdAsync(User.Identity.GetUserId());
member.HasScheduledChanges = true;
IdentityResult identityResult = appUserManager.Update(member);
如果对 Web API 的后续调用失败,我需要回滚对用户的任何更改。我知道这样的交易:
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.
}
}
}
但是在 try 块中使用 AppUserManager 完成的操作是否是事务性的?另外,他们是否使用相同的 EFDbContext 实例?换句话说,我不知道第二个代码示例开头的 var context 是否会被 try 块中的 appUserManager "Update" 方法调用使用。
此外,AppUserManager 是这样创建的:
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;
}
EFDbContext
在您的示例中是相同的 - 在这两种情况下,您都从 OWIN 上下文中解析它们,因此这不是问题。但是,Identity 是以与存储无关的方式编写的,这意味着存储机制可以由非 SQL 服务器代替。这要求 AppUserManager
内没有交易。所以你需要创建你自己的。
我经常在我的生产应用程序中使用 var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)
(只是架构稍多):
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;
}
}
使用asp.net身份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();
}
}
使用 asp.net 身份 UserManager 进行交易可能会对您有所帮助。但它对我有用,如果事务发生任何错误,它将回滚所有事务。
我正在尝试更新用户。
AppUserManager appUserManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
AppUser member = await appUserManager.FindByIdAsync(User.Identity.GetUserId());
member.HasScheduledChanges = true;
IdentityResult identityResult = appUserManager.Update(member);
如果对 Web API 的后续调用失败,我需要回滚对用户的任何更改。我知道这样的交易:
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.
}
}
}
但是在 try 块中使用 AppUserManager 完成的操作是否是事务性的?另外,他们是否使用相同的 EFDbContext 实例?换句话说,我不知道第二个代码示例开头的 var context 是否会被 try 块中的 appUserManager "Update" 方法调用使用。
此外,AppUserManager 是这样创建的:
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;
}
EFDbContext
在您的示例中是相同的 - 在这两种情况下,您都从 OWIN 上下文中解析它们,因此这不是问题。但是,Identity 是以与存储无关的方式编写的,这意味着存储机制可以由非 SQL 服务器代替。这要求 AppUserManager
内没有交易。所以你需要创建你自己的。
我经常在我的生产应用程序中使用 var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)
(只是架构稍多):
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;
}
}
使用asp.net身份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();
}
}
使用 asp.net 身份 UserManager 进行交易可能会对您有所帮助。但它对我有用,如果事务发生任何错误,它将回滚所有事务。