EF Core上下文继承复用连接引发并发操作异常的解决咨询
问题分析与解决方案
这个问题的核心原因在于你对IsolatedCustomContext的配置和继承方式,导致EF并没有真正将它视为一个独立的上下文实例来处理,进而出现了连接复用和并发操作冲突的问题。下面我们一步步拆解并解决:
1. 修正IsolatedCustomContext的构造函数依赖
你的IsolatedCustomContext目前使用的是DbContextOptions<CustomContext>,这会让EF认为它和基类CustomContext共享同一套配置(包括连接相关的上下文元数据)。你需要把构造函数的Options参数改成对应自身类型的,让EF为它生成独立的配置:
public class IsolatedCustomContext : CustomContext { // 将DbContextOptions<CustomContext>替换为DbContextOptions<IsolatedCustomContext> public IsolatedCustomContext(DbContextOptions<IsolatedCustomContext> options, DbAuthorizationOptions<CustomContext> authorizationOptions, IMemoryCache memoryCache) : base(options, authorizationOptions, memoryCache) { } }
2. 调整Startup中的上下文注册逻辑
在注册IsolatedCustomContext时,要明确为它配置独立的DbContextOptions,避免和基类共享配置。同时简化冗余的注册代码:
string connection = @"Server=localhost;Database=Custom;Trusted_Connection=True;"; // 注册主上下文 services.AddDbContext<CustomContext>(options => options.UseSqlServer(connection)); // 注册隔离上下文,独立配置它的SqlServer连接 services.AddDbContext<IsolatedCustomContext>(options => options.UseSqlServer(connection)); // 移除下面两行冗余代码,AddDbContext已经自动完成了上下文的服务注册 // services.AddTransient<DbContext, CustomContext>(); // services.AddTransient<IsolatedCustomContext>();
3. 修复控制器中的异步操作错误
你的GetCurrentUser方法存在一个明显的异步操作错误:返回类型是User,但内部调用的是异步方法FirstOrDefaultAsync(),这会导致你实际返回的是Task<User>而非User,这种错误会让上下文处于非预期的占用状态,加剧并发冲突。修正为标准的异步控制器方法:
[Route("api/[controller]")] public class UsersController : Controller { private readonly CustomContext _context; public UsersController(CustomContext context) { _context = context; } [HttpGet] // 添加async关键字,返回类型改为Task<User> public async Task<User> GetCurrentUser() { var userId = User.GetUserIdFromClaims(); // 对异步方法添加await,确保操作完成后再释放上下文 return await _context.Users.Where(x => x.Id == userId).FirstOrDefaultAsync(); } }
额外验证建议
- 确保在
AuthenticationRule.ValidateToken中,所有使用IsolatedCustomContext的异步操作都添加了await,没有遗漏的异步调用导致上下文被长时间占用。 - 如果仍有连接复用问题,可以在配置SqlServer连接时临时禁用连接池(仅用于测试,生产环境不推荐)来验证:
options.UseSqlServer(connection, o => o.Pooling(false));
生产环境建议保留连接池,通过上述上下文配置修正来解决根本问题。
内容的提问来源于stack exchange,提问作者johnny 5
相关产品推荐
相关产品推荐

