要充分發揮ADO.NET的優勢,不僅需要全面、深入理解ADO.NET程式設計模型,及時總結經驗、技巧也十分重要。 ADO已經有多年的實務經驗,ADO.NET以此為基礎,提供了更豐富、更強大的工具;儘管如此,ADO.NET的設計目標畢竟不是提供一個即插即用的工具,它不會把所有的程式設計工作簡化到僅靠滑鼠點擊就可以完成的程度。
ADO.NET包含了一大堆代表資料存取模型中各種邏輯實體的對象,其中特別連結、事務這兩個對象最為重要。連線的作用是建立一個與後端資料庫通訊的通道,建立連線物件必須以特定的.NET資料提供者為基礎。事務物件可以在現有的連線物件上建立,也可以透過明確地執行一個BEGIN TRAN SQL語句來建立。雖然理論很簡單,但實際上,圍繞連接、事務的不確定因素很多,而且它們對應用整體的穩定性和效率有著至關緊要的影響。
如何儲存連線字串,保護連線字串中可能包含的敏感資訊(例如密碼)?如何設計一個完善的資料存取策略,既考慮到安全性(即身份驗證、授權),卻又不至於對效能和可擴展性造成太大的影響?如果需要用到事務,那麼如何有效率地實現和控制事務?採用自動事務還是手動事務?在使用ADO.NET時,這些問題都必須仔細考慮。
一、連接字串,連接池
資料庫連接是一種重要的、有限的、開銷昂貴的資源,因此用好連接物件是任何應用的最基本的要求。使用資料庫連線的重點可總結如下:
保存連線字串應注意安全。
開啟連線應遲,關閉連線應早。
連接字串是存取資料庫的鑰匙。連接字串除了說明要存取的資料之外,還包含了使用者為什麼可以存取那些資料的身份證明。在執行資料庫操作時,使用者身分證明是確定資料存取權限的最重要的因素。
1.1 保存連接字串
# 目前,硬編碼的連接字串具有最佳的效能,因為它們直接編譯進了應用的程式碼之中。然而,硬編碼的字串影響程式的靈活性,一旦連接字串改變,應用程式必須重新編譯。
將連接字串保存到外部提高了靈活性,代價是存取外部字串需要付出額外的開銷。但在絕大多數情況下,由此導致的效能開銷可以忽略不計,真正需要擔心的是安全性問題。例如,攻擊者可能修改、竊取連接字串。將連接字串儲存到外部環境的常見途徑有:設定檔,UDL文件,Windows註冊表。
.NET框架設定檔以純文字檔案的形式部署,存取方便。如果連接字串包含密碼,文字格式將是最大的缺陷所在,因為密碼將以明文的形式儲存。可以考慮引入一個專用的加密/解密引擎,不過這部分工作需要開發者自己完成。
UDL文件是供OLE DB提供者使用的文字文件,也就是說,SQL Server託管提供者不支援UDL文件。 UDL檔案也存在和前面的設定檔一樣的安全性問題,總地看來優勢不多。
最後,Windows登錄可以作為一個天然安全的儲存場所。註冊表是一個保存關鍵資訊的系統知識庫,如果結合運用加密技術,可以達到較高的安全性。使用註冊表的主要缺點是部署麻煩,要求建立註冊鍵(可能還要執行加密)以及從註冊表讀取資料。雖然.NET Framework提供了一組呼叫底層Win32 API的封裝類,但這些類別都沒有提供加密功能。 aspnet_setreg.exe工具可以用來建立HKEY_LOCAL_MACHINE下的註冊鍵保存使用者名稱和密碼,例如:aspnet_setreg.exe -k "Software\MyData" -u:userID -p:password。該命令將加密指定的用戶ID和密碼。
1.2 連接池原理
# 連接池允許我們透過一個緩衝池重複使用現有的連接對象,避免每次使用連接對象時都要新建一個對象。採用連線池之後,只要少量的連線物件就可以滿足大量客戶端的需求。
每一個連接池都與一個獨立的連接字串及其事務上下文關聯。每次開啟新的連接,資料提供者會嘗試將指定的連接字串與連接池的字串進行比對。如果配對失敗,資料提供者建立新的連線並將它加入連線池。連接池被建立之後,除非進程結束,否則不會被拆除。有人認為這種處理方式會影響效能,其實不然,維護一個不活動的或是空的連線池不需要多少開銷。
連接池建立之後,系統會建立一些連接物件並將它們加入連接池,直到達到額定的最小連接物件數量。以後,系統會根據需要新建和加入連接對象,一直到達最大連接對象數量限額為止。如果程式要求連線物件時沒有空閒的連線物件可用,且連線池裡面的物件數量已達到上限,則要求被放入佇列,一旦有連線被釋放回緩衝池就立即取出使用。
避免以程式設計的方式建構連接字串。如果透過合併多個輸入資料的方式建構出連接字串,很容易給予注入式攻擊以可乘之機。如果必須使用到使用者輸入的數據,務必進行嚴格的驗證。
1.3 關閉連線
關閉一個連線時,連線物件會傳回連線池以便重複使用,但此時實際的資料庫連線並未被移除。如果停用了連線池,則實際的資料庫連線也被關閉。這裡必須強調的一點時,連接物件使用完畢後應明確關閉並將它返回給連接池,不要依靠垃圾收集器來釋放連接。實際上,當連接對象的引用超出有效範圍時,連接不一定被關閉——垃圾收集器的功能是拆除代表物理連接的.NET封裝對象,但這並不意味著底層的連接也被關閉了。
呼叫Close或Dispose方法可以將連線釋放回連接池。只有當生存期結束或出現嚴重錯誤時,連接物件才會被從連接池刪除。
1.4 連接池與安全
# 如果一個應用程式的所有資料存取操作都使用相同的連接字串,連接池的優點將發揮到極限。但是,這只是一種理想化了的狀況,很可能與應用程式的其他要求存在衝突。例如,如果只使用一個連接字串,要在資料庫這一層次上執行安全控制就很困難了。
另一方面,如果讓每個使用者分別使用自己的連接字串(即為每個使用者分別設定資料庫帳戶),勢必出現大量小型的連線池,許多連線根本不會被重複使用。按照慣例,這類問題的最佳解決方案是尋找兩個極端之間的一個適當折衷點。我們可以設定一組具代表性的公用帳戶,同時修改預存程序,使之接受一個表示使用者識別的參數,預存程序根據傳入的使用者標識執行不同的操作。
二、事務模式
# 分散式企業應用離不開事務。在資料存取代碼中加入事務管理功能主要有兩種方式:手動方式,自動方式。
在手動方式中,程式設計師負責撰寫所有設定、使用交易機制的程式碼。自動(或COM+)事務則在.NET類別中加入聲明式屬性,指定執行時間物件的事務特性。自動方式方便了將多個組件配製成在同一個事務之內運作。兩種事務方式都支援本地的或分散式的事務,但自動的事務方式極大地簡化了分散式事務處理。
必須注意的是,事務是一種開銷很大的操作,所以決定使用事務之前務必再三考慮。如果確實需要使用事務,那就要盡量縮小事務的粒度,減少對資料庫的加鎖時間、加鎖範圍。例如,對於SQL Server,單一的SQL語句不需要明確地宣告事務,SQL Server會自動將每個語句當作一個獨立的事務來運作。手動的本地事務總是比其他事務快得多,因為它不需要涉及DTC(Distributed Transaction Coordinator)。
手動事務、自動事務應視為兩種不同的、互斥的技術。如果要在單一資料庫上執行事務性操作,優先考慮手動事務。當單一事務跨越多個遠端資料庫,或單一事務涉及多個資源管理器(例如,一個資料庫和一個MSMQ資源管理器),優先考慮自動事務。不管怎樣,應極力避免混合運用兩種事務模式。如果效能不是特別重要,即使只對一個資料庫操作也可以考慮使用自動事務,使程式碼更加簡潔(但速度略慢)。
總而言之,要提高資料庫存取程式碼的質量,必須深入了解ADO.NET物件模型,根據實際情況靈活運用各種技巧。 ADO.NET是一個公用的API,各種應用程式-不管是Windows窗體應用程式、ASP頁面或Web服務,都可以透過ADO.NET存取資料庫;但是,ADO.NET不是一邊接受輸入、一邊吐出結果的黑箱,而是一個由許多工具組成的工具箱。
以上是ADO.NET實用實例介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!