Heim > Datenbank > MySQL-Tutorial > Hauptteil

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

WBOY
Freigeben: 2016-06-07 15:10:51
Original
2611 Leute haben es durchsucht

首先要说明的是连接数是有限制的: 代码如下: 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);
}
Nach dem Login kopieren

运行结果如下:

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

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

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

 

可以看到数据库连接时有限制的,如果连接不关闭,而且使用的人比较多,那么系统很快就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);
});
Nach dem Login kopieren
 
Nach dem Login kopieren

就是从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();
}
Nach dem Login kopieren

运行:

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

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

 

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

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

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

再次运行:

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

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

 

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

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

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

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

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

 

 

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

 

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

 

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

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage