当前位置: 代码迷 >> C# >> ado.net的"断开"方式,是每次调用都要先连接然后断开吗
  详细解决方案

ado.net的"断开"方式,是每次调用都要先连接然后断开吗

热度:324   发布时间:2016-05-05 03:13:50.0
ado.net的"断开"模式,是每次调用都要先连接然后断开吗?
网上找到一个说明: http://blog.csdn.net/yinjingjing198808/article/details/7857810
它里面将ado.net的断开模式说明为: 利用DataAdapter对象实现数据库断开模式:


public partial class DataRead : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string str = "server=localhost;uid=sa;pwd=123456;database=DataTest";
            SqlConnection conn = new SqlConnection(str);
            string sql = "select * from student";
            SqlDataAdapter adp = new SqlDataAdapter(sql, conn);//Adepter对象
            DataSet ds = new DataSet();//DataSet对象
            adp.Fill(ds, "stu");//填充DataSet 并为当前表命名
            DataTableReader rdr = ds.CreateDataReader();
            while (rdr.Read())//读取表中数据
            {
                Response .Write("第n条数据");
            }
        }
    }

看起来并没有一个Conn.Open和Conn.Close的代码。是不是说,在这个SqlDataAdapter对象的内部,去调用了构造函数保存了一份Conn,每次Fill函数调用的时候先Open再Close?

如果是这样的话,岂不是每个操作都要先Open再Close这样效率很低啊,还不如保持连接?
------解决思路----------------------
如果你频繁使用,可以使用一个全局的链接对象,不用每次都断开
------解决思路----------------------
看你是web,那就是肯定的,当然如果你是在一个方法里需要多次链接,那你可以不关闭,等最后一次链接结束后才关闭
------解决思路----------------------
你在学习的是否知道“SqlConnection是针对连接池的操作”呢?

SqlConnection的Open、Close根本不是什么“连接、断开”物理连接,而是申请和归还连接池里的物理连接。这就好像一个超市有30个收银员同时当班就能为同时支持5000人采购的超市提供结算服务了。而连接池用100多个连接其实就能支持每秒上万个并发数据库事务操作了(如果你的应用程序没有什么“额外占用时间”的操作的话)。

所以连接池才是真正与数据库连接的。而你的SqlConenction则是需要尽快地把不用的连接归还给连接池。如果你“占有”连接池中的连接,只看眼前的错误利益而死活都不释放,那是“偷鸡不成反蚀把米”的做法。
------解决思路----------------------
假设每一个事务平均需要50毫秒进行完,而你整个网页需要3秒钟才能生成完毕,就算是你的网页需要反复使用5次数据库连接,你要在这3秒钟去占用逻辑连接而不及时释放5次吗?

从连接池里获得一个现成的连接其实很快,每秒可以执行数十万次。而你的占用连接所耗费的时间则相对来说是非常大的。实际上小气的那种做法,在你的程序恰好也很小气(只有几个、十几个用户使用)时才能得到一点点连看都看不到的蝇头小利。不是面对高负载一些的系统而设计的。
------解决思路----------------------
在开发一个支持较多人并发访问的网站服务时,如果你说你连续两段代码放在一起,你当然不需要“关闭、然后再创建和打开”同一个连接。除此以外,如果连个操作之间可能相隔0.5秒钟,那么你一定要先关闭、然后再重新创建和打开。不要追逐什么蝇头小利。
------解决思路----------------------
另外,在说明白了基本的原理概念之后,说一下你贴的这段代码的问题。

这段代码有着严重的问题。它等待到GC回收 rdr 所引用的对象时才会去执行 conn.Close() 语句,这就会在稍高负载的场合严重地频繁出现“连接池已满”的崩溃问题。

我想你看到的这个“网上说明”只注意到了 rdr 不需要显示地调用 Dispose()语句,而没有注意到这个重要的 bug。
------解决思路----------------------
引用:
你在学习的是否知道“SqlConnection是针对连接池的操作”呢?

SqlConnection的Open、Close根本不是什么“连接、断开”物理连接,而是申请和归还连接池里的物理连接。这就好像一个超市有30个收银员同时当班就能为同时支持5000人采购的超市提供结算服务了。而连接池用100多个连接其实就能支持每秒上万个并发数据库事务操作了(如果你的应用程序没有什么“额外占用时间”的操作的话)。

所以连接池才是真正与数据库连接的。而你的SqlConenction则是需要尽快地把不用的连接归还给连接池。如果你“占有”连接池中的连接,只看眼前的错误利益而死活都不释放,那是“偷鸡不成反蚀把米”的做法。

是的,连接用完赶紧关闭掉,给其他资源使用。
  相关解决方案