Home >Database >Mysql Tutorial >为什么要关闭数据库连接,可以不关闭吗?

为什么要关闭数据库连接,可以不关闭吗?

WBOY
WBOYOriginal
2016-06-07 15:10:512644browse

首先要说明的是连接数是有限制的: 代码如下: for ( int i = 0; i 10000; i++){ SqlConnection conn = new SqlConnection( @Data Source=.\SQLEXPRESS; AttachDbFilename= E:\DB\NORTHWND.mdf ; Integrated Security=True;Connect Timeout=30;User Instance

首先要说明的是连接数是有限制的:

代码如下:

<span>for</span> (<span>int</span> i = 0; i new SqlConnection(<span>@"Data Source=.\SQLEXPRESS;
                AttachDbFilename="</span><span>"E:\DB\NORTHWND.mdf"</span><span>";
                Integrated Security=True;Connect Timeout=30;User Instance=True"</span>);

    conn.Open();
    Console.WriteLine(<span>"打开了{0}个连接"</span>, i);
}

运行结果如下:

为什么要关闭数据库连接,可以不关闭吗?

过一会就会提示打开连接超时了:

为什么要关闭数据库连接,可以不关闭吗?

 

可以看到数据库连接时有限制的,如果连接不关闭,而且使用的人比较多,那么系统很快就down掉了。

 

但是有时候由于某些原因应用程序可能只是几个人使用,所以就有人设计了:

在应用程序启动的时候打开数据库连接,在应用程序关闭的时候关闭数据库连接

那么使用这种方式有什么问题呢?

首先假设有一张表Nums,表定义如下:

为什么要关闭数据库连接,可以不关闭吗?

Main代码如下:

SqlConnection conn = <span>new</span> SqlConnection(<span>@"Data Source=.\SQLEXPRESS;
                    AttachDbFilename="</span><span>"E:\DB\NORTHWND.mdf"</span><span>";
                    Integrated Security=True;Connect Timeout=30;User Instance=True"</span>);
conn.Open();
Parallel.For(1, 9999, (id) =>
{
    ExecuteCommand(conn, id);
});
 

就是从1到9999开始执行ExecuteCommand

 

ExecuteCommand代码如下:

<span>private</span> <span>static</span> <span>void</span> ExecuteCommand(SqlConnection conn, <span>int</span> id)
{
    Console.WriteLine(<span>"正在执行."</span> + id);

    Thread.Sleep(100);

    SqlCommand cmd = <span>new</span> SqlCommand(
       <span>string</span>.Format(<span>"Insert into Nums values('{0}') "</span>, id), conn);

    cmd.ExecuteNonQuery();
}

运行:

为什么要关闭数据库连接,可以不关闭吗?

可以看到ExecuteNonQuery方法抛出了异常,原因是连接处于关闭状态。

 

可是我们的连接一直都是open着的啊,并没有调用close,dispose之类的方法啊

于是在ExecuteCommand前面增加判断条件:

<span>if</span> (conn.State != System.Data.ConnectionState.Open)
    conn.Open();

再次运行:

为什么要关闭数据库连接,可以不关闭吗?

可以看到还是会出现连接已关闭的问题。你知道什么原因吗?

 

这里是由于多线程环境引起的。所以需要加锁。

<pre class="brush:php;toolbar:false"><span>private</span> <span>static</span> <span>object</span> syncObj = <span>new</span> <span>object</span>();
<span>private</span> <span>static</span> <span>void</span> ExecuteCommand(SqlConnection conn, <span>int</span> id)
{
    <span>lock</span> (syncObj)
    {
        <span>if</span> (conn.State != System.Data.ConnectionState.Open)
            conn.Open();
        Console.WriteLine("<span>正在执行..</span>" + id);
        Thread.Sleep(100);
        SqlCommand cmd = <span>new</span> SqlCommand(
           <span>string</span>.Format("<span>Insert into Nums values('{0}') </span>", id), conn);
        cmd.ExecuteNonQuery();
    }
}


再次运行:可以发现基本没问题了.

修改Parallel.For的最大值上限,要测试下是否可以长期执行了。

<pre class="brush:php;toolbar:false">Parallel.For(1, Int32.MaxValue, (id) =>
            {
                ExecuteCommand(conn, id);
            });

 

 

一天测试下来,没出现任何问题。

 

结论对于某些只有几个人使用的应用程序,可以不关闭数据库连接,但是在写代码的时候最好要加上连接是否打开的判断。

 

你有什么好的看法呢,欢迎留下!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn