关于数据库连接的一些小知识点

由于在数据库连接部分,新建连接的时候一直报“出错原因:超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。”于是,我便想查看一下数据库的活动连接,看看究竟是哪个程序占用了过多的数据库连接。

我们可以用sp_who(或sp_who2)来显示所有活动的连接。

USE master;
GO
EXEC sp_who2;
GO

查询的结果如表1。为了可读性,表1中的结果有删减了一些列和一些行。但删去的内容不影响我们要讲的东西。

表1 sp_who2查询的结果

从表1中,我们可以看到有很多进程状态(见Status列)显示sleeping,并且当前正在执行的命令类型(见Command)显示AWATING COMMAND。

     我们就有疑问,为什么有这么多的连接进程。首先,我们要明确一个概念,SQL Server 不会建立任何连接池,ADO.Net会。当我们在C#代码中打开一个数据库连接后,如果是首次连接,SqlClient就会打开一个SQL Server的连接。当我们从程序里面关闭这个连接时,SqlClient并不是真正地关闭了这个数据库的连接,而是延后一段时间才关闭,默认是60秒。如果你没有在指定延时内重新连接,SqlClient就真正地关闭这个连接。但如果你重连接了,SqlClient就会重用这个连接。这样子,我们就可以使用相同的连接属性。

     但是有几种可能的情况可能导致失败,也就是连接不能重用(或在指定的时间内没有关闭)。比如当你使用ExecuteReader的时候,没有成功地取回所有的行和结果集,继而在连接上没有将reader关闭,可能导致这个问题。

     常用的排查数据库连接问题的方法是运行SQL Server Profiler(使用默认模板)。如果你看到一个Audit Login事件,就说明有一个新的连接已经被建立。如果你看到event RPC:Completed with the text "sp_reset_connection",这说明在连接池中的一个连接被重用。如果你一直没有看到任何的sp_reset_connection,那就意味着你遇到问题了。SQL Server Profiler如图1所示。

                                                         图1 SQL Server Profiler

 

 

补充知识:

sp_who和 sp_who2的区别

sp_who是官方支持的,有文档可查。sp_who2不是官方支持的,查不到对应的文档,但它更常被使用。他们返回相同的信息:提供有关 Microsoft SQL Server 数据库引擎实例中的当前用户、会话和进程的信息。但是sp_who2额外添加了一些sp_who没有提供的列。并且,sp_who2中的信息更紧凑,更适合用文本来显示。Kalman 写道:它增加了额外的spid列来增加结果的可读性.

 

后记:

”超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小" 这个问题可能是进行查询的时候,没有成功的查询造成的。比如说执行存储过程的时候,原来需要提供给存储过程3个参数,但你只提供了两个,这就会导致查询出现错误。当错误发生的时候,原先的数据库连接就不能成功被释放或重用,这就导致了ADO.Net要继续创建新的数据库连接,最终导致了线程池中达到了池本身能够容纳的指定连接数,最终导致新的连接不能继续在线程池中创建。

参考链接:

SQL Server Profiler使用方法

SQL Server 2005联机丛书

sp_who, sp_who2和sp_who3

SLEEPING/AWAITING COMMAND question

作者:kissazi2 
出处:http://www.cnblogs.com/kissazi2/ 
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/kissazi2/p/3216297.html

时间: 2024-08-04 00:11:28

关于数据库连接的一些小知识点的相关文章

jquery-jQuery一个小知识点,求教

问题描述 jQuery一个小知识点,求教 本来不想麻烦大神的,今天看视频教程$().ready(function(){ }); 和$(document).ready(function(){ });我百度了没有明确结果,希望比较懂Js的大神告诉我一声,这两个是不是一样的 解决方案 两者效果是一样的,当没有写document的时候,默认就是选中document$().ready(function () { } )与javascript中的onload=function ( ){ };效果也是一样的

ListView小知识点及技巧

小知识点: ListView添加header以后.ListView中的item的position变为从1开始而不再是从0开始. 需求描述: ListView原本有数据.先将ListView滑动到底部,再重新加载数据.加载完成后显示ListView的头部而不是仍然在底部 解决办法: adapter.notifyDataSetChanged(); listView.setAdapter(adapter);  

(杂)小知识点

以后的小知识点都保存在这里 ComponentName            public void onClick(View v) {  //组件名称,第一个参数是包名,也是主配置文件Manifest里设置好的包名  第二个是类名,要带上包名                      ComponentName com = new ComponentName("com.dujin", "com.djy.dudu");                  Intent

一些LinuxC的小知识点(二)

一.read系统调用       系统调用read的作用是:从与文件描述符filedes相关联的文件里读入nbytes个字节的数据,并把它们放到数据区buf中.它返回实际读入的字节数.这可能会小于请求的字节数.如果read调用返回0,就表述未读入任何数据,已经达到了文件尾.同样,如果返回的是-1,就表示read调用出现了错误. #include <unistd> size_t read(int filedes,void *buf,size_t nbytes); 二.普通文件(file)和设备文

一些LinuxC的小知识点(一)

以下代码在Federo9上试验成功.   一.格式化输入16进制字符串 printf("Format:%.2x\n",10); 输入结果:   二.测试各类型的占用的字节数 int main(int argc, char *argv[]) { int OutputHex = 1; unsigned char aValue=10; char Buffer[10]; int len=sprintf(Buffer, OutputHex ? "%.2X " : "

Java中的小知识点总结

最近在复习Java的基础,遇到了一些比较偏的考核题目,特地总结一下需要注意的知识点!不过在使用IDE编程的时候,这些问题都会马上被IDE识别出来,编译是通不过的.我在这里提出来就相当于给初学者一些贡献吧   一.声明局部变量是的一些特性和规则(1)声明的局部变量是不会被默认初始化的,成员变量则是会被默认初始化的.例如: 复制代码 代码如下: class Demo {         public static void main(String[] args) {            Strin

sql server 2005学习点滴(小知识点)

server 1.启用数据库的全文索引      USE AdventureWorks;      GO      EXEC sp_fulltext_database 'enable';      GO2.从数据库中删除所有目录      USE AdventureWorks;      GO      EXEC sp_fulltext_database 'disable';      GO

c小知识点-C语言里面的EOF与 傻傻分不清楚

问题描述 C语言里面的EOF与n傻傻分不清楚 eof和n如何区别 作为初学者,不太懂. 谢谢 解决方案 n是换行(0),eof是结束(-1) 比如 char c = getchar() ; if (c == '') 换行 以及 if (scanf("%c", &c) == EOF) 输入结束 解决方案二: n 回车, 是一个字符 eof 文件结束符 -1 解决方案三: #define EOF -1 回车->'rn' 解决方案四: eof End of file n是回车符

Java中的小知识点总结_java

一.声明局部变量是的一些特性和规则(1)声明的局部变量是不会被默认初始化的,成员变量则是会被默认初始化的.例如: 复制代码 代码如下: class Demo {         public static void main(String[] args) {           String s;           System.out.println(s);     }} 上面的这段示例代码中,直接输出s是错误的,连编译都不同通过,因为在main方法中声明s,这时s是局部变量,不会被默认初始