【數據庫開發】數據庫鏈接池及其工做原理

對於一個簡單的數據庫應用,因爲對於數據庫的訪問不是很頻繁。這時能夠簡單地在須要訪問數據庫時,就新建立一個鏈接,用完後就關閉它,這樣作也不會帶來什麼明顯的性能上的開銷。可是對於一個複雜的數據庫應用,狀況就徹底不一樣了。頻繁的創建、關閉鏈接,會極大的減低系統的性能,由於對於鏈接的使用成了系統性能的瓶頸。

鏈接複用。經過創建一個數據庫鏈接池以及一套鏈接使用管理策略,使得一個數據庫鏈接能夠獲得高效、安全的複用,避免了數據庫鏈接頻繁創建、關閉的開銷。

對於共享資源,有一個很著名的設計模式:資源池。該模式正是爲了解決資源頻繁分配、釋放所形成的問題的。把該模式應用到數據庫鏈接管理領域,就是創建一個數據庫鏈接池,提供一套高效的鏈接分配、使用策略,最終目標是實現鏈接的高效、安全的複用。


數據庫鏈接池的基本原理是在內部對象池中維護必定數量的數據庫鏈接,並對外暴露數據庫鏈接獲取和返回方法。如:


外部使用者可經過getConnection 方法獲取鏈接,使用完畢後再經過releaseConnection 方法將鏈接返回,注意此時鏈接並無關閉,而是由鏈接池管理器回收,併爲下一次使用作好準備。

css

 

數據庫鏈接池技術帶來的優點

1. 資源重用

因爲數據庫鏈接獲得重用,避免了頻繁建立、釋放鏈接引發的大量性能開銷。在減小系統消耗的基礎上,另外一方面也增進了系統運行環境的平穩性(減小內存碎片以及數據庫臨時進程/線程的數量)。

2. 更快的系統響應速度

數據庫鏈接池在初始化過程當中,每每已經建立了若干數據庫鏈接置於池中備用。此時鏈接的初始化工做均已完成。對於業務請求處理而言,直接利用現有可用鏈接,避免了數據庫鏈接初始化和釋放過程的時間開銷,從而縮減了系統總體響應時間。

3. 新的資源分配手段

對於多應用共享同一數據庫的系統而言,可在應用層經過數據庫鏈接的配置,實現數據庫鏈接池技術,幾年錢也許仍是個新鮮話題,對於目前的業務系統而言,若是設計中尚未考慮到鏈接池的應用,那麼…….快在設計文檔中加上這部分的內容吧。某一應用最大可用數據庫鏈接數的限制,避免某一應用獨佔全部數據庫資源。

4. 統一的鏈接管理,避免數據庫鏈接泄漏

在較爲完備的數據庫鏈接池實現中,可根據預先的鏈接佔用超時設定,強制收回被佔用鏈接。從而避免了常規數據庫鏈接操做中可能出現的資源泄漏。一個最小化的數據庫鏈接池實現。html


對於共享資源,有一個很著名的設計模式:資源池(resource pool)。該模式正是爲解決資源頻繁分配、釋放所形成的問題。數據庫鏈接池的基本思想就是爲數據庫鏈接創建一個「緩衝池」。預先在緩衝池中放入必定數量的鏈接,當須要創建數據庫鏈接時,只須要從緩衝池中取出一個了,使用完畢後再放回去。咱們能夠經過設定鏈接池最大數來防止系統無盡的與數據庫鏈接。更爲重要的是咱們能夠經過鏈接池的管理機制監視數據庫鏈接使用數量,使用狀況,爲系統開發,測試以及性能調整提供依據。java

鏈接池的相關問題分析:sql

一、併發問題。數據庫

  爲了使鏈接管理服務具備最大的通用性,必須考慮多線程環境,併發問題。這個問題相對比較好解決,由於各個語言自身提供了併發管理的支持,好比java c#等,使用synchronized(java)  lock(c#)等關鍵字確保線程同步。編程

二、事務管理。c#

  咱們知道,事務具備原子性,此時要求對數據庫操做符合「ALL-ALL-NOTHING」原則,即對於一組sql語句要麼全作,要麼全不作。咱們知道當兩個線程共用一個鏈接connection對象時,並且各自都有本身的事務要處理時,對於鏈接池是一個很頭疼的問題,由於即便connection類提供了相應的事務支持,但是咱們仍然不能肯定那個數據庫操做對應那個事務。知識因爲咱們的兩個線程都在進行事務操做。爲此咱們可使用每個事物獨佔一個鏈接來實現,雖然這種方法有點浪費鏈接池資源可是能夠大大下降事務管理的複雜性。設計模式

三、鏈接池的分配與釋放安全

  鏈接池的分配與釋放,對系統的性能有很大的影響。合理的分配與釋放,能夠提升鏈接的複用度,從而下降創建新鏈接的開銷,同時還能夠加快用戶的訪問速度。
  對於鏈接的管理可以使用一個List。即把已經建立的鏈接都放入List中去統一管理。每當用戶請求一個鏈接時,系統檢查這個List中有沒有能夠分配的鏈接。若是有就把那個最合適的鏈接分配給他(如何能找到最合適的鏈接文章將在關鍵議題中指出);若是沒有就拋出一個異常給用戶,List中鏈接是否能夠被分配由一個線程來專門管理捎後我會介紹這個線程的具體實現。多線程

四、鏈接池的配置與維護

  鏈接池中到底應該放置多少鏈接,才能使系統的性能最佳?系統可採起設置最小鏈接數(minConnection)和最大鏈接數(maxConnection)等參數來控制鏈接池中的鏈接。比方說,最小鏈接數是系統啓動時鏈接池所建立的鏈接數。若是建立過多,則系統啓動就慢,但建立後系統的響應速度會很快;若是建立過少,則系統啓動的很快,響應起來卻慢。這樣,能夠在開發時,設置較小的最小鏈接數,開發起來會快,而在系統實際使用時設置較大的,由於這樣對訪問客戶來講速度會快些。最大鏈接數是鏈接池中容許鏈接的最大數目,具體設置多少,要看系統的訪問量,可經過軟件需求上獲得。
  如何確保鏈接池中的最小鏈接數呢?有動態和靜態兩種策略。動態即每隔必定時間就對鏈接池進行檢測,若是發現鏈接數量小於最小鏈接數,則補充相應數量的新鏈接,以保證鏈接池的正常運轉。靜態是發現空閒鏈接不夠時再去檢查。

 

引用記數

  在分配、釋放策略對於有效複用鏈接很是重要,咱們採用的方法也是採用了一個頗有名的設計模式:reference counting(引用記數)。該模式在複用資源方面使用很是普遍,咱們把該方法運用到對於鏈接分配釋放上。每個數據庫鏈接,保留一個引用記數,用來記錄該連接的使用者的個數。具體實現上,咱們對connection類進行了進一步包裝來實現引用記數。被包裝的connection類咱們提供2個方法來實現引用記數的操做,一個是repeat(被分配出去)一個是remove(被釋放回來);而後利用repeatnow屬性來肯定當前引用多少,具體是哪一個用戶引用了該鏈接,將在鏈接池中登記;最後提供isRepeat屬性來肯定該鏈接是否可使用引用記數技術。一旦一個鏈接被分配出去,那麼就會對該鏈接的申請者進行登記,而且增長引用記數,當被釋放回來時就刪除他登記的信息,同時減小一次引用記數。這樣作的一個很大的好處是,使得咱們能夠高效的使用鏈接,由於一旦全部鏈接都被分配出去,咱們就能夠根據相應的策略從使用池中挑出一個正在使用的鏈接來複用,而不是隨便拿出一個鏈接去複用。

 

 

        鏈接池用於建立和管理數據庫鏈接的緩衝技術,緩衝池中的鏈接能夠被任何須要他們的線程使用。當一個線程須要使用JDBC對一個數據庫操做時,將從池中請求一個鏈接。當這個連接使用完畢後,將返回鏈接池中,等待爲其餘的線程服務。

  鏈接池的主要優勢:

1)減小鏈接的建立時間,鏈接池中的鏈接是已準備好的,能夠重複使用的,獲取後能夠直接訪問數據庫,所以減小了鏈接建立的次數和時間。

2)簡化的編程模式。當使用鏈接池時,每個單獨的線程可以像建立本身的JDBC鏈接同樣操做,容許用戶直接使用 JDBC編程技術。

3)控制資源的使用。若是不使用鏈接池,每次訪問數據庫都須要建立一個鏈接,這樣系統的穩定性受系統的鏈接需求影響很大,很容易產生資源浪費和高負載異常。鏈接池可以使性能最大化,將資源利用控制在必定的水平之下。鏈接池能控制池中的連接數量,加強了系統在大量用戶應用時的穩定性。

鏈接池的工做原理:

鏈接池的核心思想是鏈接的複用,經過創建一個數據庫鏈接池以及一套鏈接使用、分配和管理策略,使得該鏈接池中的鏈接能夠獲得高效,安全的複用,避免了數據庫鏈接頻繁創建和關閉的開銷。

鏈接池的工做原理主要由三部分組成,分別爲鏈接池的創建,鏈接池中鏈接的使用管理,鏈接池的關閉。

第1、鏈接池的創建。通常在系統初始化時,鏈接池會根據系統配置創建,並在池中創建幾個鏈接對象,以便使用時能從鏈接池中獲取,鏈接池中的鏈接不能隨意建立和關閉,這樣避免了鏈接隨意創建和關閉形成的系統開銷。java中提供了不少容器類,能夠方便的構建鏈接池,例如Vector,stack等。

第2、鏈接池的管理。鏈接池管理策略是鏈接池機制的核心,鏈接池內鏈接的分配和釋放對系統的性能有很大的影響。其策略是:

當客戶請求數據庫鏈接時,首先查看鏈接池中是否有空閒鏈接,若是存在空閒鏈接,則將鏈接分配給客戶使用;若是沒有控線鏈接,則查看當前所開的鏈接數是否已經達到最大鏈接數,例如若是沒有達到就從新建立一個請求的客戶;若是達到,就按設定的最大等待時間進行等待,若是超出最大等待時間,則拋出異常給客戶。

當客戶釋放數據庫鏈接時,先判斷該鏈接的引用次數是否超過了規定值,若是超過了就從鏈接池中刪除該鏈接,不然就保留爲其餘客戶服務。該策略保證了數據庫鏈接的有效複用,避免了頻繁創建釋放鏈接所帶來的系統資源的開銷。

第3、鏈接池的關閉。當應用程序退出時,關閉鏈接池中全部的連接,釋放鏈接池相關資源,該過程正好與建立相反。

相關文章
相關標籤/搜索