自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

DataReader鏈接關閉解惑篇

運維 數(shù)據(jù)庫運維 SQL Server
看到有帖子:DataReader的關閉問題疑惑篇 ,大伙對鏈接關閉問題看似比較迷惑,這里就給解說一下:不管是啥xxDataReader,都是繼承DataReader實現(xiàn)的,所以是有共性的,因此標題就以DataReader為題了。

看到有帖子:DataReader的關閉問題疑惑篇 ,大伙對鏈接關閉問題看似比較迷惑,這里就給解說一下:

不管是啥xxDataReader,都是繼承DataReader實現(xiàn)的,所以是有共性的,因此標題就以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();  

結(jié)論是:

False

Open

說明:默認無論是不是加System.Data.CommandBehavior.CloseConnection,讀取時數(shù)據(jù)庫鏈接不會幫你關閉。

情況二: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. }  

結(jié)果是:

True

Closed

情況:System.Data.CommandBehavior.CloseConnection加完之后,鏈接給你關閉了,為啥?看下面的分析原因。

三:分析原因

1:從前面的兩個示例上看,區(qū)別是什么?

答:區(qū)別就在于一個只讀數(shù)據(jù),另一個綁定了數(shù)據(jù)列表控件。

2:為什么綁定了數(shù)據(jù)列表控件就會自動關閉鏈接?

答:這就涉及到數(shù)據(jù)控件綁定機制了,這里給大伙簡單介紹一下:

A:要實現(xiàn)數(shù)據(jù)控件列表綁定,有一個接口是需要實現(xiàn)的:IEnumerable

B:實現(xiàn)DataReader實現(xiàn)此接口的代碼[基類是抽象方法,所以只能到子類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. }  

點進去只看到構(gòu)造函數(shù),并把它賦給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())//此方法被調(diào)用一次,就讀一次  
  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;//有數(shù)據(jù)時直接返回,不會執(zhí)行下面的關閉鏈接  
  14.     }  
  15.     if (this.closeReader)//好,能進行這里,說明上面讀不到數(shù)據(jù),簡說就是數(shù)據(jù)讀完了  
  16.     {  
  17.         this._reader.Close();//關閉鏈接操作。  
  18.     }  
  19.     return false;  
  20. }  

以上代碼就看我注釋的說明。

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

答:因為服務端控件列表渲染出表格的周期通常比較長,所以,只有等到你看到最后結(jié)果列表出來的時候,最后一行數(shù)據(jù)才讀完。

因此鏈接是持續(xù)相當長的處于打開狀態(tài),所以web這種并發(fā)多的情況,狂點幾下,估計就報錯了,鏈接池用滿了。

四:最終結(jié)論是什么?

1:在綁定列表控件時,只要數(shù)據(jù)行讀取完畢,就會自動關閉鏈接。

2:在直接讀取時,不會觸發(fā)綁定相關的讀取,所以不會自動關閉鏈接。

3:在綁定列表控件時,鏈接長期得不到關閉,并發(fā)一來,就掛了,因此大伙就不要耍流氓了。

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

責任編輯:艾婧 來源: 博客園
點贊
收藏

51CTO技術棧公眾號