zoukankan      html  css  js  c++  java
  • 连接池泄露了~

        做这个项目有近三个月了,在测试网页时总是感觉速度挺慢,但是一直没有发现是哪里的问题。前几天做的一个比较复杂页面中,一个按钮就调用了几次数据访问层的方法,这样反复几次操作之后页面就会崩掉,返回的错误大致是:连接池中的连接已达到最大上限,不能在打开新的连接了。原来是连接池泄露了

        我在数据库访问层中写的方法都是调用MS的SQLHelpe类中提供的方法来直接访问数据库的,其中的ExecuteReader方法如下:

    public static SqlDataReader ExecuteReader(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) 
            
    {
                SqlCommand cmd 
    = new SqlCommand();
                SqlConnection conn 
    = new SqlConnection(connString);

                
    // we use a try/catch here because if the method throws an exception we want to 
                
    // close the connection throw code, because no datareader will exist, hence the 
                
    // commandBehaviour.CloseConnection will not work
                try 
                
    {
                    PrepareCommand(cmd, conn, 
    null, cmdType, cmdText, cmdParms);
                    SqlDataReader rdr 
    = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                    cmd.Parameters.Clear();
                    
    return rdr;
                }

                
    catch 
                
    {
                    conn.Close();
                    
    throw;
                }

            }


        既然有CommandBehavior.CloseConnection了,我想读取完数据连接就应该自动关闭了吧,就没在我的代码里手动关闭,结果反而就是上了这个自动关闭的当了。在William Vaughnm文章里,他说到了连接池泄露的几种可能性:

        “当代码完成 DataReader 后,您要在 SqlConnection 对象停止作用之前关闭 SqlConnection。要处理行集,您可以将 DataReader 传递到应用程序中的另一个例程,但仍然需要确保 DataReader 及其连接处于关闭状态。如果您不关闭 SqlConnection,代码会“泄漏”每个操作的连接,于是连接池对连接进行累积,最后便发生溢出。与 ADO 和 Visual Basic (VB) 6.0 中的情况不同,.NET 垃圾回收器不会为您关闭 SqlConnection 并进行清理。

        “您也可能在使用 DataAdapter 对象时遇到问题。DataAdapter Fill 和 Update 方法可自动打开 DataAdapter 对象的连接,并在数据 I/O 操作完成后关闭该连接。不过,如果该连接在执行 Fill 或 Update 方法时已经处于打开状态,那么,ADO.NET 在方法执行完以后不会关闭 SqlConnection。这是另一个发生连接“泄漏”的机会。”

        既然CommandBehavior.CloseConnection不能够保证在使用完连接后关闭它,那么它有什么用呢?

        “只有当您在 ASP.NET Web 应用程序中使用复杂的绑定控件时,该选项才以这种方式工作。在整个 DataReader 结果集中循环到其行集的末尾(也就是说,当 Dr.Read — DataReader 的 Read 方法 — 返回 False 时)还不足以触发连接的自动关闭。不过,如果您绑定到一个复杂的绑定控件(例如,DataGrid),该控件则会关闭 DataReader 和连接 ”

        在每次使用完SQLHelper返回的DataReader对象之后加上一个手动关闭Reader的语句,在每次使用完SQLHelper的更新数据库操作之后都加上关闭数据库连接的语句,问题得到解决。

  • 相关阅读:
    Spring中Model,ModelMap以及ModelAndView之间的区别
    ssm框架中Controller层的junit测试_我改
    Controller、Service、Dao进行Junit单元
    ssm controller层 junit单元测试
    spring常用注解
    Spring MVC测试框架
    ssm框架junit简单测试_我写
    spring注入时报错::No qualifying bean of type 'xxx.xxMapper'
    Eclipse 报 "The builder launch configuration could not be found" 错误
    IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)
  • 原文地址:https://www.cnblogs.com/supersand/p/415047.html
Copyright © 2011-2022 走看看