互联网解决方案咨询

梦想有多大路就会有多远:作一颗IT量子
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据库开发-数据库连接池的问题

Posted on 2008-04-12 17:26  互联网粒子  阅读(262)  评论(0编辑  收藏  举报

由于连接池不用于一般的数据连接,一旦发生连接泄漏应用程序就可能死锁或崩溃,所以我们应该慎重的处理。

       也许不少人在ADO.NET下的编程模式还是这样的:

  SqlConnection conn = new SqlConnection(conn);

  //执行SqlProcedure

   conn.Close();

然而,这就象是公式定律一样的编撰方法,在假如你使用了connection pool的情况下,就变成了隐藏的杀手,因为谁也不能保证你的SqlProcedure是否正确的执行了,或者这些代码发生一些意想不到的异常,假如这段代码在连接打开了,但没有关闭的情况下就引发了一个异常,但是负责编撰数据访问层的Client的程序员可能很聪明的捕获了该异常,并告知用户操作失败是否重试。应用程序暂时运行正常了,但连接泄漏了…..

当被泄漏的连接超时却仍未被释放或返回连接池,将再次抛出一个异常。

数据访问代码编撰者的任务之一就是杜绝该异常的抛出。

于是我又看到有的代码这样写,的确可以防止连接泄漏:

 

using (SqlConnection conn = new SqlConnection(connectionString)) {

                //执行SqlProcedure

                return result;

            }

 

       我们可能会遇到两种情况,方法要么是返回数据,要么返回DataReader,但using语句块只支持返回数据。我们可以使用try….catch…finally语句。

       前一种的解决方法除了使用using语句,还有就是在实现方法时就应该考虑最坏的情况,即代码执行失败,我们应该捕获该异常但不处理,当我们在数据层把清理工作做完,再把异常抛出让别人去处理

            SqlConnection conn = new SqlConnection(connectionString);

            SqlCommand cmd = new SqlCommand();

            try

            {

                //………………

                return cmd.ExecuteNonQuery();

            }

            finally

            {

                if (conn.State == ConnectionState.Open)

                    conn.Dispose();

                cmd.Connection = null;

                cmd.Parameters.Clear();

                cmd.Dispose();

            }

 }

 

       而对付DataReader,我们有更简单的办法,就是CommandBehavior.CloseConnection枚举。

            SqlCommand cmd = new SqlCommand();

            SqlConnection conn = new SqlConnection(connectionString);

            try

            {

              //.....................

                SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

                cmd.Parameters.Clear();

                return rdr;

            }

            catch

            {

                if (conn.State == ConnectionState.Close)

                conn.Dispose();

                throw;

            }

     DataReader使用了CommandBehavior.CloseConnection枚举以后,就可以调用DataReaderClose()Dispose()方法关闭数据连接。如果你把返回的DataReader绑定到DataGridView控件上,它会自动关闭连接。但如果绑定到简单控件上就必须显式的调用DataReader.Close()