【发布时间】:2012-09-25 00:48:27
【问题描述】:
我有一个 Windows 服务,它通过 RabbitMQ 接收消息,这会触发一个事件处理程序,它会做一些工作,然后尝试将结果保存到数据库中。它的线程使用:
ThreadPool.QueueUserWorkItem(ProcessMessageOnThread, messageReceived);
其中ProcessMessageOnThread 是在messageReceived 上执行工作的方法,messageReceived 表示从 RabbitMQ 出列的消息。
正常情况下windows服务按预期运行,即出队、处理、持久化。
我想确保我的所有消息都得到处理并给予公平的更改以进行处理,因此如果我无法打开与 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()
【问题讨论】:
标签: c# sql-server design-patterns connection-pooling