在 .NET Framework 版本 4 上
我发现 mono 4.2.2 上的 SQL Server ADO.NET 实现中可能存在并发问题,当客户端上的查询被取消或超时时,该问题就会显现出来,使用 SqlCommand.ExecuteReader
API。
重现现场看到的问题:
我每秒同时运行 3 个新的定时任务,这些任务运行 3 - 5 个相对较小的查询并完成并返回(全部使用
SqlCommand.ExecuteReader
),这按预期运行。然后,我向测试运行添加一个长时间运行的查询,设置为每 65 秒执行一次,但在 60 秒后取消。查询需要超过 60 秒才能完成,因此每次都会被取消(使用
SqlCommand.Cancel()
)。运行几分钟后,突然大多数迭代
SqlDataReader
的尝试都返回错误,因为返回的行上不存在预期的字段,因此当数据层尝试访问时他们按名字命名,但有一个异常(exception)。
添加日志记录代码以打印行上的字段表明它们来自作为测试一部分运行的另一个查询,因此该查询要么同时运行,要么最近运行。
一旦某个查询出现这个问题,这种情况确实发生得非常频繁,事实上大多数查询都会失败。在现场,即使是每分钟只尝试服务 5 个左右查询的服务,对于大多数查询也会返回错误的记录集
。
重新启动进程可以解决问题。
仅供引用
- 每个查询都会实例化一个新的连接、命令和读取器对象,并与它们自己的“using” block 一起使用。
- 正在使用 ADO.NET 的默认连接池
- 大多数连接都连接到同一个数据库,每个任务运行一次都会与另一台服务器上的另一个数据库建立单独的连接,但这总是成功完成。
- 代码已经成熟,并且在 Windows .NET 框架系统上的生产中使用没有问题,并且在 Windows .NET 框架上运行相同的测试无法重现该问题,因此这不太可能是跨两个平台的问题。<
还有其他人看到过这个并可以告诉我我可能做错了什么吗?简单地禁用连接池是否可以(临时)解决此问题?
最佳答案
经过进一步测试,显式禁用连接池实际上确实可以解决这个问题,但当然这会带来额外的开销,特别是对于查询频率较高的应用程序
关于sql-server - 如何避免 Mono ADO.NET 在超时后向请求提供错误结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37446935/