DataReader链接关闭解惑篇

运维 数据库运维 SQL Server
看到有帖子:DataReader的关闭问题疑惑篇 ,大伙对链接关闭问题看似比较迷惑,这里就给解说一下:不管是啥xxDataReader,都是继承DataReader实现的,所以是有共性的,因此标题就以DataReader为题了。

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

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

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

示例代码:

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

结论是:

False

Open

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

情况二:DataReader 链接已关闭

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

  1. protected void bind()  
  2. {  
  3.     SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["constr"].ToString());  
  4.     conn.Open();  
  5.     SqlCommand cmd = new SqlCommand("GetAllUser", conn);  
  6.     SqlDataReader sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);  
  7.     repeater1.DataSource = sdr;  
  8.     repeater1.DataBind();  
  9.     Response.Write(sdr.IsClosed.ToString() + "<br/>");  
  10.     Response.Write(conn.State.ToString());  
  11. }  

结果是:

True

Closed

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

三:分析原因

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

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

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

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

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

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

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

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

  1. public DbEnumerator(IDataReader reader, bool closeReader)  
  2. {  
  3.     if (reader == null)  
  4.     {  
  5.         throw ADP.ArgumentNull("reader");  
  6.     }  
  7.     this._reader = reader;  
  8.     this.closeReader = closeReader;//此行设置了标志  
  9. }  

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

  1. public bool MoveNext()  
  2. {  
  3.     if (this._schemaInfo == null)  
  4.     {  
  5.         this.BuildSchemaInfo();  
  6.     }  
  7.     this._current = null;  
  8.     if (this._reader.Read())//此方法被调用一次,就读一次  
  9.     {  
  10.         object[] values = new object[this._schemaInfo.Length];  
  11.         this._reader.GetValues(values);  
  12.         this._current = new DataRecordInternal(this._schemaInfo, values, this._descriptors, this._fieldNameLookup);  
  13.         return true;//有数据时直接返回,不会执行下面的关闭链接  
  14.     }  
  15.     if (this.closeReader)//好,能进行这里,说明上面读不到数据,简说就是数据读完了  
  16.     {  
  17.         this._reader.Close();//关闭链接操作。  
  18.     }  
  19.     return false;  
  20. }  

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

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

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

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

四:最终结论是什么?

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

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

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

原文链接: http://www.cnblogs.com/cyq1162/archive/2011/04/06/2006412.html

责任编辑:艾婧 来源: 博客园
相关推荐

2011-04-07 09:20:12

DataReader关闭问题

2010-05-24 18:16:52

MySQL数据库

2009-12-17 14:56:11

Ruby关闭IE进程

2009-12-21 18:32:22

关闭WCF链接

2009-09-03 10:26:07

C#修改DataRea

2009-11-04 12:45:33

ADO.NET Dat

2011-04-28 11:04:22

DataReader分页

2021-02-04 17:06:46

工具代码开发

2011-04-14 09:42:06

DataReaderDataSet

2016-10-14 15:00:45

2017-07-11 16:45:51

Python整数比较

2017-09-12 15:56:43

边缘计算云计算架构

2009-10-29 11:08:20

ADO.NET Dat

2009-07-20 10:36:29

什么是JDBC

2012-03-23 14:02:11

云计算

2009-11-13 10:31:07

ADO.NET Dat

2013-11-01 10:51:10

OSPF邻居邻接

2019-04-02 10:50:05

框架Spring开发

2018-06-06 10:14:32

Kafka时间轮任务

2019-03-25 20:46:22

混合IT云计算私有云
点赞
收藏

51CTO技术栈公众号