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:在绑定列表控件时,链接长期得不到关闭,并发一来,就挂了,因此大伙就不要耍流氓了。

 

好了,打完收工,希望对大伙有所帮助。

相关文章
|
6月前
|
Oracle 关系型数据库 Java
plsql链接远程Oracle数据库步骤
实际工作中,我们往往需要使用 PLSQL Develope 工具连接远程服务器上的 ORACLE 数据库进行管理,但是由于 ORACLE 安装在本地电脑步骤繁琐,并且会耗费电脑的很大一部分资源,因此,我们寻求一种不需要在本地安装 ORACLE 数据库而能直接使用 PLSQL Develope 工具连接到远程服务器 ORACLE 的方法。
108 2
|
6月前
|
C语言 Python
编程中打开和关闭文件
编程中打开和关闭文件
37 0
|
数据库
【乌拉喵.教程】InterBase7.0数据库的建立且与Delphi2010的连接
【乌拉喵.教程】InterBase7.0数据库的建立且与Delphi2010的连接
|
C# 数据库
C#编程-65:读取数据库DataReader对象复习笔记
C#编程-65:读取数据库DataReader对象复习笔记
C#编程-65:读取数据库DataReader对象复习笔记
|
C# 数据库
C#编程-65:数据库Command对象复习笔记
C#编程-65:数据库Command对象复习笔记
C#编程-65:数据库Command对象复习笔记
|
关系型数据库 MySQL 数据库连接
C#连接Mysql数据库,我的第一个wpf项目记录
C#连接Mysql数据库,我的第一个wpf项目记录
C#连接Mysql数据库,我的第一个wpf项目记录
|
SQL 关系型数据库 MySQL
QTP连接MYSQL数据库方法
1.首先安装mysql数据驱动,qtp在windows系统下操作连接mysql,所以下载mysql-connector-odbc-   5.1.8-win32.msi    下载地址:http://mysql.mirrors.pair.com/Downloads/Connector-ODBC/5.1/mysqlconnector-odbc-5.1.8-win32.msi 2.安装mysql驱动 ,默认安装即可。
1027 2
ArcEngine“不能再打开其它表了”的解决方法
查询的时候遇到ArcEngine“不能再打开其它表了”,突然间想起项目经理给我以前说的要把游标释放掉,当时不明白为什么,认为这个没有什么的呀,不就是一条条取数据吗?这次却发现这个问题了,原来是查询过于频繁,游标来不及释放,所以会出现问题,用System.Runtime.InteropServices.Marshal.ReleaseComObject()就可以解决。
761 0
|
MySQL 关系型数据库 Java
Hibernate用Mysql数据库时链接关闭异常的解决
在一个项目中,客户要求除操作系统外全部使用免费软件,因此我使用了Mysql 4.0作为数据库服务器,其JDBC驱动为3.0.9版本,在给客户安装后调试一切正常。可是到了第二天,只要一登录就提示“No operations allowed after connection closed”异常,显示在浏览器上。
1665 0