我有一个运行在Windows上的服务,在通过RabbitMQ接收到消息后,触发事件处理程序进行一些操作,然后尝试将结果保存到数据库中。它使用线程:
ThreadPool.QueueUserWorkItem(ProcessMessageOnThread, messageReceived);
ProcessMessageOnThread
是一个方法,用于处理从 RabbitMQ 队列中出列的消息的表示形式 messageReceived
。
在正常情况下,Windows 服务按预期运行,即出列、处理和持久化。
我希望确保所有的消息都被处理并有公平机会得到处理,因此如果无法连接到 SQL Server,我只需将消息重新排队以便再次处理它(希望那时 SQL Server 可以连上,否则该过程会继续进行 - 我可以接受这种情况)。
现在问题来了,当进程按预期运行一段时间后,SQL Server 连接池已经填满,并且然后 SQL Server 断开连接,这就是事情变得有点不稳定的时候。
可能会发生以下两种情况之一:
connection.Open()
抛出异常 - 不过我正在捕获异常,所以不用担心cmd.ExecuteNonQuery()
抛出异常 - 这是我执行存储过程的地方
第二种情况是我需要解决的。此前我认为任何在此处抛出的异常意味着我传递给存储过程的数据有问题,因此应将其从队列中移出并由其他东西进行分析。
但是,现在我认为我需要一种新的方法来处理异常,以处理与连接未实际建立有关的异常情况。
我查看了 SqlException
类,并注意到一个名为 Class
的属性,其描述为 获取从 SQL Server 返回的错误的严重级别
,现在对此的信息说:
严重级别小于等于 10 的消息是信息性的,指示由用户输入错误引起的问题。级别从 11 到 16 是用户生成的,可以由用户进行更正。级别从 17 到 25 表示软件或硬件错误。发生级别 17、18 或 19 错误时,您可以继续工作,尽管可能无法执行特定语句。
这是否意味着为解决我的异常处理问题,我只需检查 if (ex.Class > 16)
,然后重新排队消息,因为问题是连接,否则,将其丢弃,因为它很可能与发送到存储过程的格式不正确的数据有关?
所以问题是,我应该如何进行异常处理,以及如何检测调用 cmd.ExecuteNonQuery()
时抛出的异常是否由于断开连接而引起。
更新:
我之前遇到过连接没有返回池的问题(这是由于线程问题引起的),并已经解决了这些问题,所以我相信问题与连接未返回池无关。此外,连接使用的逻辑也很简单,我确保它们被一致地关闭...所以我更关心的是与 SQL Server 断开连接以及捕获 cmd.ExecuteNonQuery() 行为的答案。