• 连接池泄露了~


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

        我在数据库访问层中写的方法都是调用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的更新数据库操作之后都加上关闭数据库连接的语句,问题得到解决。

  • 相关阅读:
    1.4(java学习笔记) 面向对象内存分析
    1.3(java学习笔记)构造方法及重载
    1.2(java学习笔记)类与对象
    1.1(java学习笔记) 面向过程与面向对象
    STM32F0库函数初始化系列:GPIO配置
    STM32F4库函数初始化系列:PWM输出
    STM32F4库函数初始化系列:DMA串口接收
    STM32F4库函数初始化系列:三重ADC——DMA
    STM32F1库函数初始化系列:DMA—ADC采集
    STM32F4库函数初始化系列:串口DMA接收
  • 原文地址:https://www.cnblogs.com/supersand/p/415047.html
Copyright © 2020-2023  润新知