Transactions with ASP.NET Identity UserManager(与 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 的后续调用失败,我需要回滚对用户的任何更改.我了解交易,例如:
If a subsequent call to a Web API fails, I need to roll back any changes to the user. I know about transactions, like this:
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 上下文是否会被 try 块中的 appUserManagerUpdate"方法调用使用.
But will operations done with AppUserManager inside the try block be transactional? Also, do they use the same instance of EFDbContext? In other words, I don't know if var context at the start of the second code example would be used by the appUserManager "Update" method call in the try block.
此外,AppUserManager 是这样创建的:
Also, AppUserManager is created like this:
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 Server 替代.这需要 AppUserManager 内部缺少事务.所以你需要创建你自己的.
EFDbContext in your examples are the same - in both cases you resolve them from OWIN context, so this is not an issue. However, Identity is written in storage-agnostic fashion, meaning storage mechanism can be replaced by non SQL Server. This calls for lack of transactions inside of AppUserManager. So you need to create your own.
我经常在我的生产应用程序中使用 var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)(只有更多的架构):
I'm routinely using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled) in my production applications (only with a bit more 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;
}
}
这篇关于与 ASP.NET Identity UserManager 的事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:与 ASP.NET Identity UserManager 的事务
基础教程推荐
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- .NET SerialPort DataReceived 事件未触发 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- WPF 模态进度窗口 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- C# 从 List<List<int>> 中删除重 2022-01-01
- Moq It.Is<>不匹配 2022-01-01
