ADO網站資料庫技術速成
刊登於RUN!PC雜誌 1999年 3月份
作者 喬篷科技 周世雄
筆者為微軟台北廳、經銷商訓練、TechNet等研討會講師,和微軟之友、RUN!PC雜誌專欄作者,著作有「ASP網站熱門應用技術」、「微軟熱門Web技術速成班」等網站網頁設計十幾本電腦書籍。現任「喬篷科技」公司總經理,從事Internet、Intranet之Web資料庫應用設計、網站網頁規劃架設等服務。
IIS 4.0示範網站:www.asp.com.tw
連絡E-mail:jackchou@tpts5.seed.net.tw。
網際網路存取資料庫
如何透過網際網路或intranet,存取伺服器資料庫的資料呢?
答案為使用瀏覽器,透過網際網路或intranet,經由於網站伺服器IIS執行的ASP(Active Server Pages)程式,來呼叫ADO(ActiveX Data Object)、或RDS(Remote Data Service)物件,再透過各種ODBC(或OLE DB)的驅動程式,即可連接到超過50種支援ODBC(或OLE DB)的資料庫,包括Access、Excel、FoxPro、dBase、SQL Server、Oracle等資料庫,也可以連接到Excel、或Text檔案。
您只要於網站伺服器IIS的電腦上,安裝這種資料庫的ODBC(或OLE DB)的驅動程式,即可以存取位於網路上任何一台電腦支援ODBC(或OLE DB)的資料庫。
ADO使用Recordset物件
使用Recordset(記錄集合)物件,將資料庫的資料先儲存到Recordset當中,就可以讓多位使用者同時存取同一個資料庫。
ADO如何使用Recordset物件呢?
ADO如何鎖定RecordSet的記錄呢?
使用Recordset(記錄集合)物件的方法如下:
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open SQL指令, Conn, 1, 1 ‘讀取
rs.Open SQL指令, Conn, 1, 3 ‘新增、修改、或刪除
到底rs.Open後接的第三個參數1和第四個參數是甚麼意思呢?為何第四個參數於讀取時要用1,新增、修改、或刪除時要用3呢?
第三個參數表示cursor類型。
第四個參數表示RecordSet的鎖定型態。
詳細介紹如下:
RecordSet的鎖定
當開啟Recordset物件時,您也可以於LockType屬性指定鎖定的型態:
1:唯讀(ReadOnly),不允許更新,為預設值。
2:悲觀鎖定( Pessimistic lock),在編輯Recordset資料或呼叫了AddNew方法,一開始執行就立即鎖定此筆資料記錄或包含資料記錄的資料頁,並維持鎖定直到使用Update方法將變更寫回到資料庫為止。
3:樂觀鎖定(Optimistic lock),使用Update方法將變更寫回到資料庫時才鎖定此筆資料記錄。
4:批次樂觀鎖定(Batch Optimistic lock),使用UpdateBatch方法將多筆變更的記錄批次寫回到資料庫時,才鎖定此批資料記錄。
當您使用悲觀鎖定(Pessimistic Lock)時,一旦編輯Recordset資料或呼叫了AddNew方法時,就會鎖定包含目前編輯RecordSet的資料對應頁,直到明確地確認(Commit)或取消這個RecordSet的變更後,它才會釋放這個鎖定。
悲觀鎖定的主要優點,是取得鎖定之後,只要RecordSet還被鎖定著,就不會發生任何鎖定衝突。由於一個使用者開始編輯RecordSet後,其他使用者就無法改變它,所以悲觀鎖定是保證應用程式能讀取到目前最新資料的唯一方法。
悲觀鎖定的缺點,是在編輯和鎖定該RecordSet當中,包含該RecordSet的整個資料對應頁都會被鎖定。如果當使用者開始編輯和鎖定RecordSet後,在RecordSet被鎖定期間過了很久才明確地確認(Commit)或取消這個RecordSet的變更,就將產生一個問題,這不僅鎖定了使用者正在編輯的RecordSet,而且還可能會鎖定存在於該被鎖定資料對應頁內其它的RecordSet。
當您使用樂觀鎖定(Optimistic Lock)時,只會在使用Update方法變更RecordSet時,才鎖定該資料對應頁,所以能使鎖定的時間為最短,這是樂觀鎖定的主要優點。
樂觀鎖定的缺點,是當使用者開始編輯RecordSet時,無法確定更新是否會成功。如果另一個使用者改變了第一個使用者正在編輯的RecordSet,那麼建立在樂觀鎖定的更新將會失敗。
譬如甲和乙都在編輯相同的RecordSet,若甲開始以樂觀鎖定編輯一個RecordSet,因為 甲使用的是樂觀鎖定,並沒有真正鎖定該RecordSet,所以無法禁止乙嘗試編輯相同的RecordSet。
於是乙開始編輯相同的RecordSet。但是,乙也不知道甲正在編輯該RecordSet,也看不到最新的資料。
因為乙也正在編輯該資料錄,所以當甲嘗試儲存他的變更時,就會收到一個錯誤。
當您使用異動(transaction)功能時,樂觀鎖定將會轉換成悲觀鎖定。因為在你做交易確認(Commit)之前,異動一直會做寫入鎖定 (Write-Lock)的功能,所以轉換成悲觀鎖定。
樂觀更新(optimistic update)是逐筆記錄進行的。您可以讓使用者能在自己的電腦中,暫存(cache)多筆記錄的變更,然後使用批次處理,一次把這些多筆變更的記錄傳給伺服器進行更新,這樣效率比較高。這個方式稱為批次樂觀更新(Batch Optimistic Update)。
批次樂觀更新使用的鎖定方式為批次樂觀鎖定(Batch Optimistic lock),使用UpdateBatch方法將多筆變更的記錄批次寫回到資料庫時,才鎖定此批資料記錄。
在Recordset物件上設定鎖定時,如果鎖定失敗,則會產生錯誤。
譬如有另一個使用者以鎖定的模式,開啟了Recordset物件時,那麼當您嘗試鎖定該Recordset物件時,就會發生錯誤。
cursor
cursor(資料指標)是一個指標或指標的集合,它指向根據某條件從資料庫中取回的資料。cursor的特性如下:
可以表示單一資料表中的部份或全部RecordSet。
可以表示多資料表的連結(join)中的部份或全部RecordSet。
可以表示沒有RecordSet。
在cursor層次上或者在資料欄層次上,cursor可以是唯讀的或可更新的。
cursor既可以雙向捲動(表示在RecordSet中能向前或向後捲動),又可以是僅向前捲動。
cursor可以存在於用戶端的電腦中,也可以存在於伺服器上。
cursor所在位置
cursor需要暫存的資源來儲存資料,這些資源為RAM、虛擬記憶體、暫存檔或資料庫。如果這些資源在用戶端的電腦中,cursor就稱為client-side(用戶端)cursor。對於這種類型的cursor,伺服器將cursor所代表的資料和cursor自身需要的資料傳到用戶端,由用戶端電腦來管理暫存的資源。
另外一種類型的cursor,稱為server-side(伺服端)cursor。對於這種類型的cursor,使用伺服器上的暫存資源來管理RecordSet物件。對於server-side cursor,只有由cursor選中的RecordSet才透過網路傳送給用戶端的電腦。因此在網路通訊或頻寬出現問題時,使用這種類型的cursor在性能上有很大的提昇。但是,因為需要伺服器上的RAM和磁碟空間等資源,因此必須保證伺服器有足夠資源來管理所有客戶端電腦請求的cursor。
CursorLocation屬性,可以選擇cursor的所在位置,是在用戶端電腦還是伺服器上:
3:使用用戶端cursor。此選項對小的RecordSet效果較好,但對大的結果集,其性能迅速下降。
2:使用伺服端cursor。對於大多數的大型作業來說,這種類型的cursor有較好的性能。
cursor類型
當開啟Recordset物件時,可以於CursorType屬性指定不同的cursor類型:
0:Forward-only(只向前):只能向前捲動,這是預設值。
1:Keyset(索引鍵集)
2:Dynamic(動態)
3:Static(靜態)
如果應用程式只需要讀取一個RecordSet,並不需要做新增、修改、刪除的動作,那麼用Forward-only(只向前)的Recordset物件,可以明顯提高應用程式的執行性能。