.NET 8迁移后EF Core启用MARS查询触发传输层错误排查
问题:.NET 8 EF Core 启用MARS时触发物理连接不可用错误
A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
我正将代码从.NET Framework迁移至.NET 8,遇到上述错误。查询逻辑很简单:
await _dbContext .Set<Setting>() .Where(setting => setting.Type == type) .ToListAsync(cancellationToken);
发现当查询结果少于80条时无错误,超过则触发错误;移除连接字符串中的MultipleActiveResultSets=True;后错误消失。我不确定是否该移除该配置,且认为数据量不足以引发此异常。为何在EF Core中启用MARS会触发该错误,而之前在.NET Framework中正常?
解答
核心原因:EF Core与EF6对MARS的处理逻辑差异
.NET Framework中使用的EF6和.NET 8的EF Core,在MARS(多活动结果集)的连接管理上有本质区别:
- EF6对MARS的会话兼容性做了更多兼容处理,连接状态的校验和复用逻辑更宽松,即使结果集较大,也不容易触发连接异常。
- EF Core的连接池机制更严格,当启用MARS时,同一个物理连接会被用于多个逻辑会话,当结果集达到一定规模(你的场景是80条,实际和单条数据大小、网络环境相关),会话间的资源竞争或状态同步问题会导致SQL Server返回物理连接不可用的错误。
是否需要保留MARS?
- 如果没有MARS依赖场景:完全可以移除
MultipleActiveResultSets=True,这不会影响常规的CRUD操作,还能彻底解决这个问题。MARS仅在需要同时使用同一个连接执行多个查询时才有用(比如嵌套查询、一边读取查询结果一边执行更新),如果你的代码没有这类场景,没必要保留。 - 必须使用MARS的场景:可以尝试以下方案:
- 调整连接字符串的数据包大小:添加
Packet Size=8192;(默认是4096),减少数据传输的数据包数量,降低连接状态异常的概率。 - 排查异步代码是否存在阻塞:确保没有在异步方法中调用
.Result或.Wait()这类同步阻塞操作,这种操作会干扰MARS的连接状态管理。 - 临时禁用连接池排查:在上下文配置中添加
options.UseSqlServer(connStr, o => o.DisableConnectionPooling()),如果错误消失,说明是连接池和MARS的交互问题,但禁用连接池会影响性能,仅作为排查手段,不建议长期使用。
- 调整连接字符串的数据包大小:添加
内容的提问来源于stack exchange,提问作者Kyle Fuller
相关产品推荐
相关产品推荐

