You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.0中AspNetUsers表事务不生效问题求助

解决ASP.NET Core Identity事务不一致问题

你遇到的核心问题是_userManager.CreateAsync方法内部会自动调用SaveChanges()提交AspNetUser表的修改,导致这部分操作脱离了你手动创建的事务控制,出现了部分表数据提前保存的情况。下面给你两种可行的解决方案,以及问题根源的详细解释:

解决方案一:使用TransactionScope统一管理事务

这种方式可以让所有操作(包括Identity的用户创建)都处于同一个事务上下文,只要不调用Complete(),所有变更都会在异常时自动回滚。

第一步:配置DbContext支持事务

在Startup.cs的ConfigureServices中,修改DbContext的注册代码,开启事务支持:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();
        // 配置SQL Server并启用事务支持
        options.UseSqlServer(configuration["ConnectionStrings:IdentityConnection"], 
            o => o.EnableRetryOnFailure().EnlistTransaction(Transaction.Current));
    },ServiceLifetime.Scoped);
    
    // 其他Identity相关注册代码...
}

第二步:修改Register方法使用TransactionScope

public async Task<IActionResult> Register([FromBody]AccountBindingViewModel model)
{
    // 启用异步事务流支持
    using (var transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
        try
        {
            // 保存自定义Users表数据
            applicationDbContext.Add(new Users() { Name = "Rishi" });
            await applicationDbContext.SaveChangesAsync();
            
            // 创建Identity用户
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email, PhoneNumber = model.PhoneNumber };
            var result = await _userManager.CreateAsync(user, model.Password);
            
            if (result.Succeeded)
            {
                var savedUser = await _userManager.FindByEmailAsync(model.Email);
                if (savedUser != null)
                {
                    SaveEntity(savedUser, model); // 保存其他表数据
                    // throw new Exception(); // 测试回滚时可以取消注释
                    transactionScope.Complete(); // 确认提交所有事务
                }
            }
            return Ok();
        }
        catch (Exception ex)
        {
            // 异常时事务自动回滚
            return BadRequest(new { Message = "注册失败:" + ex.Message });
        }
    }
}

解决方案二:手动控制Identity用户的保存流程

绕过UserManager.CreateAsync的自动保存逻辑,手动处理用户密码哈希并将用户添加到DbContext,让所有变更都由你手动控制提交。

public async Task<IActionResult> Register([FromBody]AccountBindingViewModel model)
{
    using (var dbTransaction = await applicationDbContext.Database.BeginTransactionAsync())
    {
        try
        {
            // 保存自定义Users表数据
            applicationDbContext.Add(new Users() { Name = "Rishi" });
            
            // 手动创建Identity用户并处理密码哈希
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email, PhoneNumber = model.PhoneNumber };
            var passwordHash = _userManager.PasswordHasher.HashPassword(user, model.Password);
            user.PasswordHash = passwordHash;
            applicationDbContext.Users.Add(user);
            
            // 批量保存所有变更(包括自定义表和AspNetUser表)
            await applicationDbContext.SaveChangesAsync();
            
            var savedUser = await _userManager.FindByEmailAsync(model.Email);
            if (savedUser != null)
            {
                SaveEntity(savedUser, model); // 保存其他表数据
                await applicationDbContext.SaveChangesAsync();
                // throw new Exception(); // 测试回滚时可以取消注释
                await dbTransaction.CommitAsync(); // 提交事务
            }
            return Ok();
        }
        catch (Exception ex)
        {
            await dbTransaction.RollbackAsync(); // 手动回滚事务
            return BadRequest(new { Message = "注册失败:" + ex.Message });
        }
    }
}

问题根源解释

默认的_userManager.CreateAsync方法内部会自动调用DbContext.SaveChanges(),这个操作如果没有被纳入统一的事务上下文,就会直接将AspNetUser表的变更提交到数据库,而你手动创建的事务只覆盖了自己调用SaveChanges()的操作,最终导致事务不一致。

上面两种方案分别通过全局事务包裹和手动控制保存流程的方式,让所有数据库操作都处于同一个事务控制下,确保要么全部提交,要么全部回滚。

内容的提问来源于stack exchange,提问作者rishi kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:22:22