ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL Server断开连接导致连接池问题

2019-11-27 16:06:43  阅读:508  来源: 互联网

标签:connection-pooling c sql-server design-patterns


我有一个Windows服务,该服务通过RabbitMQ接收消息,这会触发一个事件处理程序,该事件处理程序会做一些工作,然后尝试将结果持久化到数据库中.它使用以下方法进行线程化:

ThreadPool.QueueUserWorkItem(ProcessMessageOnThread, messageReceived);

其中,ProcessMessageOnThread是一种对messageReceived进行工作的方法,该消息表示从RabbitMQ出队的消息.

在正常情况下,Windows服务会按预期运行,即出队,处理和保留.

我想确保所有消息都得到处理,并给予公平的对待更改,因此,如果我无法打开与SQL Server的连接,我只需重新排队该消息以使其再次处理(希望那时候SQL Server将回来,否则会继续-我对此表示满意.

现在,当进程按预期的时间运行了一段时间,SQL Server连接池已满,然后SQL Server断开连接时,问题就来了,此时情况变得有些不稳定.

可能发生以下两种情况之一:

> connection.Open()引发异常-但是我正在捕获此异常,因此不必担心
> cmd.ExecuteNonQuery()引发异常-这是我执行存储过程的地方

这是我需要弄清楚如何处理的第二个选项.以前,我认为这里的任何异常都意味着我要传递给存储过程的数据存在问题,因此应该将其移出队列并进行其他分析.

但是,现在我认为我需要一种新的方法来处理与未实际建立连接有关的异常情况.

我查看了SqlException类,并注意到一个名为Class的属性,该属性具有以下描述获取从SQL Server返回的错误的严重性级别,现在有关此信息的信息为:

Messages with a severity level of 10 or less are informational and indicate problems caused by mistakes in information that a user has entered. Severity levels from 11 through 16 are generated by the user, and can be corrected by the user. Severity levels from 17 through 25 indicate software or hardware errors. When a level 17, 18, or 19 error occurs, you can continue working, although you might not be able to execute a particular statement.

这是否意味着要修复我的异常处理,我只能检查是否(例如Class> 16)然后重新排队,因为问题出在连接上,否则将其丢弃,因为它最有可能是将格式错误的数据发送到存储的程序?

因此,问题是,如果引发异常是由于连接断开引起的,我应该如何进行异常处理以及如何在调用cmd.ExecuteNonQuery()时进行检测.

更新:

以前,我曾遇到过一些问题,因为连接没有返回到池中(这是由于线程问题所致),并且已经解决了这些问题,所以我有信心,该问题与连接不回到池中无关.另外,围绕连接使用的逻辑非常简单,我还要确保它们始终处于关闭状态……所以我对与断开Sql Server的连接然后捕获行为的答案更感兴趣. cmd.ExecuteNonQuery()的

解决方法:

由于各种原因,连接池中的连接可能会进入怪异状态,所有这些都与不良的应用程序设计有关:

>在关联数据读取器之前关闭连接
>更改不会重置池的设置(例如事务隔离级别)
>启动异步查询(BeginOpenReader),然后在异步处理程序触发之前将连接返回到池

您应该调查您的应用程序,并确保将连接正确返回到池中.可以帮助调试的一件事是在开发设置中减小应用程序池的大小.您可以在连接字符串中更改池的大小:

...;Integrated Security=SSPI;Max Pool Size=2;Pooling=True;

这使得合并问题非常容易重现.

如果找不到原因,但仍需要部署修复程序,则可以使用ClearPool或ClearAllPools之一.这样做的一个好地方是在Open()或ExecuteNonQuery()之后检测到可疑异常之一.两者都是SqlConnection类上的静态方法:

SqlConnection.ClearPool(yourConnection);

或更粗略的方法:

SqlConnection.ClearAllPools()

请注意,这基本上是Pokémon Exception Handling.如果它起作用,您将不知道为什么.

标签:connection-pooling,c,sql-server,design-patterns
来源: https://codeday.me/bug/20191127/2075435.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有