看到有帖子: ,大伙对链接关闭问题看似比较迷惑,这里就给解说一下:
不管是啥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:要实现数据控件列表绑定,有一个接口是需要实现的:
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:在绑定列表控件时,链接长期得不到关闭,并发一来,就挂了,因此大伙就不要耍流氓了。
好了,打完收工,希望对大伙有所帮助。
版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:
http://www.cnblogs.com/cyq1162/archive/2011/04/06/2006412.html