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