ASP 3.0高級編程(3108)
發(fā)表時間:2023-08-03 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]8.3.3 使用連接狀態(tài) 將連接字符串存入應(yīng)用程序變量是一個常用的技巧,同使用一個包含文件一樣有效。例如,可以在global.asa文件中加入下面的代碼: Sub Appli...
8.3.3 使用連接狀態(tài)
將連接字符串存入應(yīng)用程序變量是一個常用的技巧,同使用一個包含文件一樣有效。例如,可以在global.asa文件中加入下面的代碼:
Sub Application_OnStart()
strConn = "Provider=SQLOLEDB; Data Source=WATCHER; " & _
"Initial Catalog=pubs; User Id=davids; Password=whisky"
Set Application("ConnectionString") = strConn
End Sub
在ASP頁面中,可以使用下面的代碼:
Set conPubs = Server.CreateObject("ADODB.Connection")
conPubs.Application("ConnectionString")
從個人的角度,我更喜歡使用包含文件的方法,因?yàn)槲覍懥嗽S多不同的連接到各種服務(wù)器和數(shù)據(jù)庫的例子。使用應(yīng)用程序方法將意味著每次必須關(guān)閉瀏覽器重新啟動應(yīng)用程序。讀者可以使用自己喜歡的任一種方法,在速度上它們并沒有差別。
對于在本書的這節(jié)內(nèi)的例子,將使用一個含有連接字符串的connection.asp文件人作為一個包含文件。
8.3.4 連接語法
上面所敘述的是相關(guān)理論,當(dāng)確實(shí)要與數(shù)據(jù)存儲連接時,應(yīng)該怎么辦?如果使用顯式定義的Connection對象,可以使用Open方法,它的語法如下:
connection.Open [ConnectionString], [UserID], [Password], [Options]
參數(shù)如表8-1所示:
表8-1 Open方法的參數(shù)及說明
參 數(shù)
說 明
ConnectionString
包含連接細(xì)節(jié)的字符串?梢允荗DBC DSN的名稱、數(shù)據(jù)鏈接文件的名稱或真實(shí)的連接細(xì)節(jié)
UserID
連接期間,用戶使用的名字。覆蓋連接字符串中提供的任何用戶名
Password
用戶的口令。覆蓋連接字符串中提供的任何口令
Options
可以是adAsyncConnect,指定異步地建立連接。忽略這個參數(shù),則建立一個同步連接
異步連接不用于ASP環(huán)境,因?yàn)槟_本語言不能接收來自ADO的事件。
8.3.5 連接的例子
下面是幾個示例,這里假定strConn包含一個有效的連接字符串。
為了打開一個連接,使用Connection對象的Open方法。例如:
Set conPubs = Server.Connection("ADODB.Connection")
conPubs.Open strConn
' Some processing
conPubs.Close
也可以使用ConnectionString屬性:
Set conPubs = Server.CreateObject("ADODB.Connection")
conPubs.ConnectionString = strConn
conPubs.Open
' Some processing
conPubs.Close
這兩種實(shí)現(xiàn)方法之間沒有什么區(qū)別,如果使用前一種方法來實(shí)現(xiàn)連接,ConnectionString屬性同時也被賦值。
值得注意的是,一旦與數(shù)據(jù)存儲建立了連接,ADO可能會改變ConnectionString屬性值。不必?fù)?dān)心,ADO只填寫一些額外的屬性值。
8.3.6 連接緩沖池
連接緩沖池(connection pool)總使許多人感到困惑,其實(shí)原理非常簡單。當(dāng)關(guān)閉一個連接,就用戶(和ADO)而言,這個連接已經(jīng)關(guān)閉。但實(shí)際上OLE DB并沒有關(guān)閉這個連接,只是將其放入了非活動的連接緩沖池中。任何時候用戶(或其他人)打開一個連接,OLE DB首先檢測連接緩沖池中是否有相同連接細(xì)節(jié)的連接存在。如果有,將直接從緩沖池中取得此連接。如果沒有,則為用戶創(chuàng)建一個新的連接。為了避免浪費(fèi)資源,經(jīng)過一段缺省的時間段后,就從緩沖池中清除該連接。
那么,它的優(yōu)點(diǎn)在哪里?打開一個連接可能是所進(jìn)行的操作中最慢的操作之一,連接緩沖池使用戶能與數(shù)據(jù)存儲再次連接而無須重新創(chuàng)建連接。這對于那些連續(xù)打開和關(guān)閉大量連接的Web站點(diǎn)顯得特別重要。
對于ODBC連接,連接緩沖池由ODBC Data Source Administrator控制。對于OLE DB,不能改變連接緩沖池(或叫會話緩沖池)。
必須注意的是,連接緩沖池不是連接共享。一個連接只有在被客戶關(guān)閉后才能再次使用。
內(nèi)務(wù)處理
為了使連接緩沖池生效,必須確保內(nèi)務(wù)處理(Housekepping)處于有序狀態(tài)。這包括及時關(guān)閉Connection對象,這樣它們才能回到緩沖池重新使用。你可能認(rèn)為不斷地打開、關(guān)閉連接對系統(tǒng)的開銷很大,但必須衡量一下可擴(kuò)展性——你的應(yīng)用程序可能有許多人在使用,OLE DB又非常善于管理連接資源。
一般的原則是:盡可能晚地建立連接,同時又要盡可能早地關(guān)閉連接,這樣保證連接打開的時間段最短。
8.4 記錄集
前面已經(jīng)提到,記錄集是ADO中最常用的對象,這并不值得奇怪。畢竟,他們包含著數(shù)據(jù)。但是,對于記錄集還有比想象的更多的內(nèi)容,知道數(shù)據(jù)如何保存和處理很重要,因?yàn)檫@為選擇使用哪種記錄集提供了更多的參考。
記錄集有不同的類型,在一些細(xì)小的地方存在著差異,很容易造成失誤。首先需要認(rèn)真談?wù)摰氖枪鈽?biāo)的概念。
8.4.1 光標(biāo)
光標(biāo)(cursor)是讓許多人感到困惑的概念,但實(shí)際上非常的簡單。
光標(biāo)用來管理記錄集和記錄集的當(dāng)前位置,后者是由當(dāng)前記錄指針來處理的。
這不是Recordset對象所做的嗎?是的,但是記錄集也是依靠它的光標(biāo)。這仍然沒有回答光標(biāo)是什么這個問題,那么先來看一個記錄集,如表8-2所示:
AU_ID
AU_LNAME
AU_FNAME
PHONE
172-32-1176
White
Bob
408 496-7223
219-46-8915
Green
Marjorie
415 986-7020
238-95-7766
Carson
Cheryl
415 548-7723
267-41-2394
O'Leary
Michael
408 286-2428
274-80-9391
Straight
Dean
415 834-2919
341-22-1782
Smith
Meander
913 843-0462
這里有六行四列。打開一個記錄集,當(dāng)前記錄就是第一個記錄,即為Bob White的那條記錄。用什么來標(biāo)識當(dāng)前記錄?用當(dāng)前記錄指針。那么又如何處理這個指針呢?當(dāng)需要移到下一條記錄或者是其他記錄時,是通過光標(biāo)來實(shí)現(xiàn)的。在訪問當(dāng)前行的字段時,光標(biāo)知道目前位于哪一行,所以能返回正確的值。如果試圖移出記錄集的最后一行,光標(biāo)也會處理。
理解光標(biāo)的一種好方法是將光標(biāo)想象成為一個可以在記錄集內(nèi)移動的窗口。這一窗口與記錄集的單個行同樣高,同樣長,因此一次只能看到一行數(shù)據(jù)值。當(dāng)你移到另一條記錄時,這個窗口也跟著移動。
也許你認(rèn)為這相當(dāng)簡單,但它確實(shí)很重要,因?yàn)槟苡霉鈽?biāo)做什么是由光標(biāo)的類型決定的。
1. 光標(biāo)類型
光標(biāo)的類型標(biāo)識了光標(biāo)所能夠提供的功能。這里有四種類型的光標(biāo):
· 靜態(tài)(adOpenStatic)。靜態(tài)光標(biāo)含有對記錄的靜態(tài)拷貝。這意味著在記錄集建立之后,記錄集的內(nèi)容就固定了。其他用戶對記錄的更改、添加和刪除都是不可見的。允許在記錄集中向前、向后移動。
· 只許前移(adOpenForwardOnly)。缺省的光標(biāo)類型,除了只允許向前移動外,其余的與靜態(tài)光標(biāo)相同。
· 動態(tài)(adOpenDynamic)。動態(tài)的光標(biāo)沒有固定的記錄集。其他用戶的更改、添加或刪除操作在記錄集中是可見的。允許在記錄集中向前、向后移動。
· 鍵集(adOpenKeyset)。鍵集類型的光標(biāo)除了記錄集是固定的,其余的與動態(tài)光標(biāo)相似?梢钥吹狡渌脩舻男薷模掠涗泤s不可見。如果別的用戶刪除了記錄,那么這些記錄在記錄集中將會變得不可訪問。這項(xiàng)功能是通過標(biāo)識記錄集的鍵來實(shí)現(xiàn)的,所以鍵一直保留著,即使改變或刪除記錄。
為了理解這些概念,再想象光標(biāo)窗口。對于只許前移的光標(biāo),可以看作是一個位于單向齒輪上的窗口,只能向前移動。這一特點(diǎn)的有利之處在于一旦通過了一條記錄,光標(biāo)就會完全忘記該記錄,因?yàn)橛肋h(yuǎn)不會回到該記錄上。靜態(tài)光標(biāo)則移去了單向齒輪,允許向后移動;因?yàn)橐材芟蚝笠苿,光?biāo)需要跟蹤這些記錄。由于這個原因,靜態(tài)光標(biāo)比只許前移的光標(biāo)慢。
對于鍵集和動態(tài)類型的光標(biāo),窗口可以前后移動,但所看到的內(nèi)容可能會改變。鍵集光標(biāo)可以看到別人對數(shù)據(jù)的更改,但看不到新的或已刪除的記錄。因此,記錄集是固定的,但不是內(nèi)容固定。動態(tài)光標(biāo)將它擴(kuò)展了,不僅可以改變記錄的內(nèi)容,而且可以改變記錄集。所以在動態(tài)光標(biāo)中能夠看到有新的記錄出現(xiàn),同時刪除的記錄從記錄集中消失。
使用的光標(biāo)類型取決于想達(dá)到的目的。如果只想瀏覽記錄,也許是為了創(chuàng)建一個表格或一個選擇列表,那么用只許前移的光標(biāo)是最好不過了。雖然使用其他類型的光標(biāo)速度可能會慢一些,但也可以正常工作。
光標(biāo)的類型會影響性能,特別是服務(wù)器光標(biāo)。例如,在微軟的SQL Server 6.5中,鍵集和靜態(tài)類型的光標(biāo)都需要在臨時數(shù)據(jù)庫(tempdb)中放入一個完整的數(shù)據(jù)拷貝。其中,鍵集類型的光標(biāo)相比較而言稍微高效一些,因?yàn)樗粚㈡I拷入臨時數(shù)據(jù)庫。對于SQL Server 7.0情況不是這樣,不同類型的光標(biāo)的運(yùn)行效率差別不是很大。
2. 光標(biāo)位置
既然已經(jīng)解釋了什么是光標(biāo),以及光標(biāo)如何管理數(shù)據(jù),但是光標(biāo)在哪里呢?答案不是固定的,因?yàn)楣鈽?biāo)依賴于數(shù)據(jù)存儲。某些數(shù)據(jù)存儲,比如微軟的SQL Server,有自身的光標(biāo)服務(wù);而別的如微軟的Access卻沒有光標(biāo)服務(wù)。
當(dāng)打開一個記錄集時,必須選擇是否希望數(shù)據(jù)存儲管理光標(biāo),或是希望OLE DB和ADO在本地為你管理光標(biāo)。后者可以實(shí)現(xiàn)是因?yàn)镺LE DB有其自己的光標(biāo)服務(wù)。通過使用Connection對象或Recordset對象的CursorLocation屬性可以設(shè)置這兩個選項(xiàng)。可以設(shè)定該屬性的值為:
· adUseServer:讓數(shù)據(jù)存儲管理光標(biāo)。
· adUseClient:讓ADO管理光標(biāo)。
可以在打開連接或記錄集之前設(shè)置這個屬性:
conPubs.CursorLocation = adUseServer
conPubs.Open strConn
或者:
rsAuthors.CursorLocation = adUseClient
rsAuthors.Open "authors", conPubs
缺省的光標(biāo)是基于服務(wù)器的,理解這兩種類型的區(qū)別非常重要。對于一個服務(wù)器光標(biāo)來說,數(shù)據(jù)存儲的任務(wù)是管理記錄,所以,當(dāng)使用服務(wù)器光標(biāo)建立一個記錄集時,數(shù)據(jù)存儲管理著記錄的移動、記錄的更新等等。
對于一個客戶光標(biāo),記錄集的全部內(nèi)容復(fù)制給客戶,受本地客戶光標(biāo)服務(wù)管理。這意味著對于一個客戶光標(biāo),打開一個具有大量記錄的記錄集要比使用基于服務(wù)器的光標(biāo)打開相同記錄集所花費(fèi)的時間長得多。也需要使用基于客戶的光標(biāo)的時候,在本書后面,研究組件時,會看到更多的相關(guān)的例子。
3. “消防帶”光標(biāo)
你可能知道“消防帶”(Firehose)光標(biāo),由于能給應(yīng)用程序帶來高的運(yùn)行效率,所以對其進(jìn)行解釋顯得非常重要。因?yàn)椤跋缼А惫鈽?biāo)是一種特殊類型的光標(biāo),只有在與微軟的SQL Server連接時才出現(xiàn)。SQL Server創(chuàng)建用戶請求的數(shù)據(jù)集,然后把數(shù)據(jù)直接傳給客戶以使其盡可能快地得到數(shù)據(jù)。SQL Server自身幾乎沒有光標(biāo)管理,這意味著它可以更快地處理數(shù)據(jù)。也就是說數(shù)據(jù)可以在非常短的時間內(nèi)迅速返回到客戶端。從客戶方看,類型于只許前移的光標(biāo)。
那么,在前面討論光標(biāo)類型時,為什么沒有涉及到“消防帶”光標(biāo)呢?因?yàn)檫@類光標(biāo)專用于SQL Server,并僅用于使用基于服務(wù)器的光標(biāo)時。這不是一種真正的光標(biāo)類型,獲得一個“消防帶”類型光標(biāo)的方法就是不指定光標(biāo)的類型。
8.4.2 鎖定
我們已經(jīng)解釋了光標(biāo)和如何管理數(shù)據(jù)。現(xiàn)在可以創(chuàng)建記錄集了嗎?恐怕還不行,因?yàn)檫有一個問題沒有討論,那就是鎖定。
鎖定就是如何確保數(shù)據(jù)的完整性,確保更改不會被覆蓋。我們需要避免的典型情況是多次更新,比如一個用戶改動了一些數(shù)據(jù),接著另一個用戶立即又將其做了修改。為了對這種情況加以保護(hù),要鎖定記錄,有許多不同的方法可以保證記錄得到保護(hù)?赏ㄟ^鎖定類型來設(shè)置這些方法。
鎖定類型
鎖定類型決定更新記錄時記錄是否或如何被鎖定。有四種類型的鎖定:
· 只讀(adLockReadOnly):缺省鎖定類型,記錄集是只讀的,不能修改記錄。
· 悲觀的(adLockPessimistic):當(dāng)修改記錄時,數(shù)據(jù)提供者將嘗試鎖定記錄以確保成功地編輯記錄。只要編輯一開始,則立即鎖住記錄。
· 樂觀的(adLockOptimistic):直到用Update方法提交更新記錄時才鎖定記錄。
· 批量樂觀的(adLockBatchOptimistic):允許修改多個記錄,只有調(diào)用UpdateBatch方法后才鎖定記錄。
當(dāng)不需要改動任何記錄時,應(yīng)該使用只讀的記錄集,這樣提供者不用做任何檢測。對于一般的使用,樂觀的鎖定可能是最好的選擇,因?yàn)橛涗浿槐绘i定一小段時間,數(shù)據(jù)在這段時間被更新。這減少了資源的使用。
悲觀的鎖定提高了數(shù)據(jù)的完整性,但卻是以犧牲并發(fā)性為代價的。并發(fā)性是許多用戶在同一時間查閱數(shù)據(jù)的能力。鎖定的記錄對其他用戶是不可見的,因而數(shù)據(jù)的并發(fā)性降低了。樂觀的鎖定只在一小段時間內(nèi)鎖定記錄,所以增強(qiáng)了數(shù)據(jù)的并發(fā)性,但同時其他用戶修改數(shù)據(jù)的幾率也增加了。
關(guān)于并發(fā)性和鎖定的問題在微軟出版的《Inside SQL Server 7.0》(作者Ron Soukup和Kalen Delaney)中做了較好的論述。這是一本很有權(quán)威的專著,所以無論如何應(yīng)購買這本專著,該書有大量的有價值的資料。