[转] DataReader 链接关闭解惑篇

看到有帖子:SqlDataReader 的关闭问题 ,大伙对链接关闭问题看似比较迷惑,这里就给解说一下:

不管是啥 xxDataReader,都是继承 DataReader 实现的,所以是有共性的,因此标题就以 DataReader 为题了。

情况一:DataReader 默认链接不关闭

示例代码:

static void Main(string[] args)
        {
            SqlConnection con = new SqlConnection("server=.;database=MySpace;uid=sa;pwd=123456");
            con.Open();
            SqlCommand com = new SqlCommand("select top 1 id from blog_user",con);
            SqlDataReader sdr = com.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
            while (sdr.Read())
            {
            }
            Console.WriteLine(sdr.IsClosed);
            Console.WriteLine(con.State.ToString());
            Console.ReadLine();
        }

结论是:

False
Open

说明:默认无论是不是加 System.Data.CommandBehavior.CloseConnection,读取时数据库链接不会帮你关闭。

情况二:DataReader 链接已关闭

示例代码:[以下是原文的代码]

protected void bind()
        {
            SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["constr"].ToString());
            conn.Open();
            SqlCommand cmd = new SqlCommand("GetAllUser", conn);
            SqlDataReader sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            repeater1.DataSource = sdr;
            repeater1.DataBind();
            Response.Write(sdr.IsClosed.ToString() + "<br/>");
            Response.Write(conn.State.ToString());
        }

结果是:

True

Closed

情况:System.Data.CommandBehavior.CloseConnection 加完之后,链接给你关闭了,为啥?看下面的分析原因。

三:分析原因

1:从前面的两个示例上看,区别是什么?

答:区别就在于一个只读数据,另一个绑定了数据列表控件。

2:为什么绑定了数据列表控件就会自动关闭链接?

答:这就涉及到数据控件绑定机制了,这里给大伙简单介绍一下:

A:要实现数据控件列表绑定,有一个接口是需要实现的:IEnumerable

B:实现 DataReader 实现此接口的代码[基类是抽象方法,所以只能到子类 SqlDataReader 查看:

public override IEnumerator GetEnumerator()
{
    return new DbEnumerator(this, (this._commandBehavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection);
}

从这代码里,我们只看到了它把 CloseConnection 传进 DbEnumerator 里了,再进去看一下:

public DbEnumerator(IDataReader reader, bool closeReader)
    {
        if (reader == null)
        {
            throw ADP.ArgumentNull("reader");
        }
        this._reader = reader;
        this.closeReader = closeReader;//此行设置了标志
    }

点进去只看到构造函数,并把它赋给 this.closeReader 属性,因为 DataReader 是向前读方式,所以重点还是要看其中的一个方法 MoveNext:

public bool MoveNext()
    {
        if (this._schemaInfo == null)
        {
            this.BuildSchemaInfo();
        }
        this._current = null;
        if (this._reader.Read())//此方法被调用一次,就读一次
        {
            object[] values = new object[this._schemaInfo.Length];
            this._reader.GetValues(values);
            this._current = new DataRecordInternal(this._schemaInfo, values, this._descriptors, this._fieldNameLookup);
            return true;//有数据时直接返回,不会执行下面的关闭链接
        }
        if (this.closeReader)//好,能进行这里,说明上面读不到数据,简说就是数据读完了
        {
            this._reader.Close();//关闭链接操作。
        }
        return false;
    }

以上代码就看我注释的说明。

C:为什么用 DataReader 绑定列表控件是耍流氓?

答:因为服务端控件列表渲染出表格的周期通常比较长,所以,只有等到你看到最后结果列表出来的时候,最后一行数据才读完。

因此链接是持续相当长的处于打开状态,所以 web 这种并发多的情况,狂点几下,估计就报错了,链接池用满了。

四:最终结论是什么?

1:在绑定列表控件时,只要数据行读取完毕,就会自动关闭链接。

2:在直接读取时,不会触发绑定相关的读取,所以不会自动关闭链接。

3:在绑定列表控件时,链接长期得不到关闭,并发一来,就挂了,因此大伙就不要耍流氓了。

时间: 2024-07-30 16:39:05

[转] DataReader 链接关闭解惑篇的相关文章

解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。

解决Mysql连接池被关闭  ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会失去链接,导致访问失败.因此稳定解决办法是把hibernate默认的连接池换成c3p0链接池. 在Hibernate(spring管理)中的配置:<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledData

【链接】 一篇很好的有关卡特兰数的博客

内容是: 有关卡特兰数的大部分知识,特别全,基本够用了. 强推!!!!!!!!!!!!! 真的很好!!!!!!!!!!! 链接: https://blog.csdn.net/wookaikaiko/article/details/81105031 原文地址:https://www.cnblogs.com/qxyzili--24/p/11221193.html

【链接】 一篇很好的有关prufer序列的博文

虽然之后会补上自己写的[离开HZ再说吧 ,这里先推荐这一篇. 写的超级棒,挺清楚的,也挺全的. https://blog.csdn.net/morejarphone/article/details/50677172 原文地址:https://www.cnblogs.com/qxyzili--24/p/11221441.html

.net集合对象解惑篇

.Net中大量的集合对象是否曾让你头痛,那么现在就让我作为你的"导游"带着你走出来.帮助你在System.Collections名域中找到自己的方向. 集合提供了一种将任意对象格式化存储的方法,我们都知道在日常的程序设计中,它们是多么有帮助.接下来就随我找到它并认识它. 一.定义    从.NET的角度来看,一个集合可以被定义为一个实现了一个或多个System.Collections.ICollection.System.Collections.IDictionary和System.C

[转] DataReader 不奇怪,该出手时就出手!

刚看到一篇文章:[原]关于使用DataReader的一个很奇怪的问题,不应该用DataReader? 于是准备花点时间解答下,顺便为这个月增添一篇文章. 关于DataReader,以前写过一篇文章,可参考:DataReader 链接关闭解惑篇 下面将对原文,解答两个问题: 一: DataReader.DataTable.DataSet 的简单关系: 这里先取原文的第一句话:.net 读取数据集有两种方式:DataSet 和 DataReader 解答:.net 的 Command 操作里,默认可

DWR3.0 服务器推送及解惑

前言 环境搭建 建立工程 jar包填装 下载dwrjar 下载commons-loggingjar 项目目录 webxml dwrxml java文件 jsp页面 调试运行 文字展示 图片展示 解惑篇 关于自动生成的js文件 如何配置页面脚本 客户端怎么调用服务器端方法 总结 前言 昨天晚上偶然咋慕课网上看到了一个DWR的视频,一开始我还以为是DreamWaver的缩写,后来发现我错了,原来人家是Direct Web Remoting的缩写. DWR说白了是一个用于改善web页面与Java类交互

【浅墨Unity3D Shader编程】之五 圣诞夜篇: Unity中Shader的三种形态对比&amp;混合操作合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.  文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/164.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文算是固定功能Shader的最后一篇,下一次更新应该就会开始讲解表面Shader,而

JDBC——Java代码与数据库链接的桥梁

想要通过java代码实现访问数据库,并对数据库进行操作,需要以下几个步骤: 一.首先我们需要一个 .jar  包.访问不同数据库,需要的jar包也不相同 Mysql数据库jar包下载地址:http://wangpan.baidu.com/disk/home?errno=0&errmsg=Auth%20Login%20Sucess&stoken=62559320e9b55b03d45ec682d851d5598036a2dc1f8d5d1cd0d330d955fa84deff136d062a

【浅墨Unity3D Shader编程】之七 静谧之秋篇: 表面着色器的写法(二)——自定义光照模式

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/plus/view.php?aid=183 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文主要讲解了Unity中SurfaceShader的自定义光照模式的写法. 上篇文章中我们已经说到,表面着色器将分为两次讲解,上