.Net 连接池的配置Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.”

.Net 连接池的配置Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.”

ADO.Net 在数据库操作过程中默认打开了连接池,不需要再进行手工配置。这个特性可以使数据库操作时效率提高,但也要有相应的代码配合,才能真正提高程序效率。

1、连接字符串

    ADO.Net 中的连接池大小可以通过数据库连接字符串来控制,例如:

    string cs =

    "server=.;uid=sa;pwd=tcaccp;database=pubs;pooling=true;min pool size=5;max pool size=10"

    其中 pooling 表示是否打开连接池,默认为打开,关掉时需要 pooling = false;

    min pool size 表示连接池最少保存几个连接对象;

    max pool size 表示连接池最多保存几个连接对象。(最大值不能为 0,也不能小于最小值)

    配置好以后,通过 SqlConnection con = new SqlConnection(cs); 即可得到一个属于连接池的连接对象。

    但一定要注意,连接字符串的任何改动,系统都会认为是另一个完全不同的数据库连接,将会创建新的连接池,这必然会造成更大的系统开销。所以,为了保证某些连接对象属于一个连接池,连接字符串不能有任何变化,包括大小写,包括空格,都不能有任何变化。   

2、程序中的改动

    普通的数据库操作:

    SqlConnection con = new SqlConnection(cs);

    try

    {

       con.Open();

       //进行各种数据库操作

    }

    catch(Exception ex){ Console.WriteLine(ex.Message); }

    finally

    {

       con.Close();

       con.Dispose();

    }

    这个过程很繁琐,每次都要在操作完毕后保证连接对象的关闭和资源释放。在打开连接池特性以后,finally 中的内容,其实是将连接对象的状态置为关闭,然后放回到连接池中。既然系统知道要放回连接池,那有没有什么更好的方法呢?

    using(SqlConnection con = new SqlConnection(cs))

    {

       try

       {

          con.Open();

          // Do Something......

       }

        catch(Exception ex){ Console.WriteLine(ex.Message); }
    }

    .Net 中的 using 语句,不光能导入命名空间,还能在程序体内,局部使用某个对象。像上边代码,con 的作用域只有 using 对应的大括弧这么大。更神奇的是,using 可以在对象作用域结束时,自动调用 con.Dispose()将对象释放,所以以上代码中,没有 con.Close() 和 con.Dispose(),同样可以释放资源,放回连接池,省了 finally 和手工关闭的麻烦。但同时需要注意,using 既然是在结束作用域时是自动调用对象的 Dispose()方法,那就是说不是什么类型的对象都可以用 using 的方式自动释放,必须要实现 IDispose 接口。

3、监控连接池的状态

    连接池在工作状态下,是完全由系统来进行控制的,那如何监控连接池中连接对象的信息呢?

    从两方面入手:数据库服务器 和 数据库驱动程序。

    数据库服务器是连接对象的目的地,通过服务器状态的查询,就能够看到连接池对服务器的访问信息。拿 SQL Server 2005 为例,执行 sp_who 或者 sp_who2 两个系统存储过程,就可以看到所有访问数据库的连接的列表。比如 min pool size 设置为 5,表示连接池中至少要维护 5 个数据库对象,程序启动以后,执行 exec sp_who2 就可以发现,数据库中有 5 个对应数据库名的连接,如果没有操作,其状态就会处于 sleeping 状态。

    另一方面,程序的数据库操作都需要有数据库驱动程序,既然 ADO.Net 中能够自动管理连接池,那驱动程序肯定起着相当重要的作用。对驱动程序进行监控,靠得是 Windows 系统中的“性能计数器”功能。

    在我的电脑(右键)-->管理-->系统工具-->性能日志和警报-->计数器日志上点击右键,新建日志设置,随便起名 abc,出现设置对话框,“添加对象”,下拉列表中选 “.NET Data Provider for SqlServer”,添加,关闭。

    下边是数据采样间隔,比如 1 秒采集一次。切换到“日志文件”选项卡,将日志文件类型设置为“文本文件(逗号分隔)”,日志就会默认记录在“C:/PerfLogs/abc_000001.csv”里,点确定关闭窗体。

    回到“计数器日志”窗口,保证刚刚设置的 abc 处于绿色运行状态,如果是红色,可以点中 abc ,然后在工具栏中点播放按钮(黑色的三角)让其启动。

    设置好后,就可以让程序运行,其数据库连接池状态,连接对象数量,就会在“C:/PerfLogs/abc_000001.csv”里记录,需要查看时直接双击,用 Excel 打开即可。打开的文件,左侧是记录时间,上方有我们关心的:

    NumberOfPooledConnections :放入池中的连接对象数

    NumberOfActiveConnectionPoolGroups :活动的连接池组的数量

    NumberOfInactiveConnectionPoolGroups :不活动的连接池组的数量

    NumberOfActiveConnectionPools :活动的连接池数量

    NumberOfInactiveConnectionPools :不活动的连接池数量

    根据这些日志数据,我们就可以在程序运行时监控连接池状态,并根据这些数据,来调整连接池的相关设置。

你可能感兴趣的:(数据库)