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

标签: 数据库 | 发表时间:2011-08-09 06:24 | 作者:LoveJenny Raymond
出处:http://www.cnblogs.com/

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

代码如下:

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=True");

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

运行结果如下:

image

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

clip_image002

 

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

 

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

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

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

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

image

Main代码如下:

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

就是从1到9999开始执行ExecuteCommand

 

ExecuteCommand代码如下:

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

    Thread.Sleep(100);

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

    cmd.ExecuteNonQuery();
}

运行:

clip_image002[5]

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

 

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

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

if (conn.State != System.Data.ConnectionState.Open)
    conn.Open();

再次运行:

clip_image002[7]

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

 

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

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

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

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

Parallel.For(1, Int32.MaxValue, (id) =>
            {
                ExecuteCommand(conn, id);
            });

 

 

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

 

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

 

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

作者: LoveJenny 发表于 2011-08-09 06:24 原文链接

评论: 50 查看评论 发表评论


最新新闻:
· Dennis Crowley给硅谷开了一张空头支票?(2011-08-09 15:40)
· 下半年MacBook笔记本将抢夺更多PC市场份额(2011-08-09 15:17)
· Windows Phone 7已死的十大理由(2011-08-09 15:14)
· Facebook调整News Feed 好友动态按话题显示(2011-08-09 14:54)
· 逾百种智能手机易遭窃听 诺基亚苹果在列(2011-08-09 14:43)

编辑推荐:C#与闭包

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [数据库] 推荐:

数据库sharding

- - 数据库 - ITeye博客
当团队决定自行实现sharding的时候,DAO层可能是嵌入sharding逻辑的首选位置,因为在这个层面上,每一个DAO的方法都明确地知道需要访问的数据表以及查询参数,借助这些信息可以直接定位到目标shard上,而不必像框架那样需要对SQL进行解析然后再依据配置的规则进行路由. 另一个优势是不会受ORM框架的制约.

数据库索引

- - CSDN博客推荐文章
索引是由用户创建的、能够被修改和删除的、实际存储于数据库中的物理存在;创建索引的目的是使用户能够从整体内容直接查找到某个特定部分的内容. 一般来说,索引能够提高查询,但是会增加额外的空间消耗,并且降低删除、插入和修改速度. 1.聚集索引:表数据按照索引的顺序来存储的. 2.非聚集索引:表数据存储顺序与索引顺序无关.

数据库事务

- - 数据库 - ITeye博客
事务传播发生在类似以下情形:. 假设methodB的配置是:. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在事务里,那么methodB重新建立一个事务运行. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在是事务里,那么methodB在非事务中运行.

数据库优化

- - 数据库 - ITeye博客
程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点: . a) SQL的使用规范: .   i.尽量避免大事务操作,慎用holdlock子句,提高系统并发能力.   ii.尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接.   iii.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作.

数据库调优

- - 数据库 - ITeye博客
1、1、调整数据结构的设计. 这一部分在开发信息系统之前完成,程序员需要考虑是否使用ORACLE数据库的分区功能,对于经常访问的数据库表是否需要建立索引等. 这一部分也是在开发信息系统之前完成,程序员在这一步需要考虑应用程序使用什么样的体系结构,是使用传统的Client/Server两层体系结构,还是使用Browser/Web/Database的三层体系结构.

MySQL数据库的修复

- Xin - 博客园-首页原创精华区
找到mysql的安装目录的bin/myisamchk工具,在命令行中输入:. 然后myisamchk 工具会帮助你恢复数据表的索引. 好象也不用重新启动mysql,问题就解决了. 当你试图修复一个被破坏的表的问题时,有三种修复类型. 如果你得到一个错误信息指出一个临时文件不能建立,删除信息所指出的文件并再试一次--这通常是上一次修复操作遗留下来的.

Oracle 发布 NoSQL 数据库

- 冷月 - 博客园新闻频道
  Oracle 作为全球最大的关系型数据库提供商,在其产品链条中,也加入了 NoSQL 数据库这一环,而且这个新的数据库名字很霸气,就叫 NoSQL Database,想起了当年新浪微博更换 weibo.com 域名之时的一个笑话:. 原来有三家人做面包,张三家的面包叫三张牌面包,李四家的牌子叫李四牌面包,王五家出品的是王五牌面包,而突然有一天,张三家的面包改名了,叫面包牌面包.

WineHQ 数据库泄漏

- gnawux - LinuxTOY
运行于 *Nix 之上的开源跨平台 Win32 API 兼容层 WineHQ 的 AppDB 和 Bugzilla 数据库被黑客攻击. CodeWeavers CEO Jeremy 在信中提到黑客利用某种方式获取了 WineHQ 的 AppDB 和 Bugzilla 的访问,并且下载了完整数据库文件.

数据库复制-Goldengate

- - 人月神话的BLOG
参考: http://wenku.baidu.com/view/4fd7ea22bcd126fff7050b5d.html. GoldenGate TDM(交易数据管理)软件是一种基于日志的结构化数据复制软件,它通过解析源数据库在线日志或归档日志获得数据的增删改变化,再将这些变化应用到目标数据库,实现源数据库与目标数据库同步、双活.