數(shù)據(jù)庫連接池的研究與實現(xiàn)畢業(yè)設(shè)計論文.doc_第1頁
數(shù)據(jù)庫連接池的研究與實現(xiàn)畢業(yè)設(shè)計論文.doc_第2頁
數(shù)據(jù)庫連接池的研究與實現(xiàn)畢業(yè)設(shè)計論文.doc_第3頁
數(shù)據(jù)庫連接池的研究與實現(xiàn)畢業(yè)設(shè)計論文.doc_第4頁
數(shù)據(jù)庫連接池的研究與實現(xiàn)畢業(yè)設(shè)計論文.doc_第5頁
已閱讀5頁,還剩29頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

畢畢 業(yè)業(yè) 設(shè)設(shè) 計計( 論論 文文) 數(shù)據(jù)庫連接池的研究與實現(xiàn)數(shù)據(jù)庫連接池的研究與實現(xiàn) 論論文作者姓名:文作者姓名: 申申請請學(xué)位學(xué)位專業(yè)專業(yè): : 申申請請學(xué)位學(xué)位類別類別: : 指指導(dǎo)導(dǎo)教教師師姓姓名名( (職職稱稱) ): : 論論文提交日期:文提交日期: 數(shù)據(jù)庫連接池的研究與實現(xiàn)數(shù)據(jù)庫連接池的研究與實現(xiàn) 摘摘 要要 在基于 jdbc 的數(shù)據(jù)庫實際應(yīng)用開發(fā)中,對數(shù)據(jù)庫連接的管理是一個重點也 是一個難點,頻繁對數(shù)據(jù)庫的連接與關(guān)閉操作、多客戶對數(shù)據(jù)庫的并發(fā)訪問,一 定程度上決定了 web 系統(tǒng)的響應(yīng)以及應(yīng)用性能。使用數(shù)據(jù)庫連接池方式能對數(shù) 據(jù)庫的連接進行管理和維護,上層應(yīng)用程序通過數(shù)據(jù)庫連接池使用數(shù)據(jù)庫資源能 提升系統(tǒng)性能,充分利用系統(tǒng)資源。文章通過介紹、分析數(shù)據(jù)庫連接池工作的 基本原理,了解目前流行的 web 服務(wù)器在數(shù)據(jù)庫連接池方面的使用現(xiàn)狀后,總 結(jié)一了些數(shù)據(jù)庫連接池開發(fā)程序中容易忽略的問題。并在學(xué)習(xí)掌握了實現(xiàn)連接 池的關(guān)鍵技術(shù)后給出了一個較為高效的連接池管理策略,在這種策略思想的指 導(dǎo)下實際開發(fā)出一個數(shù)據(jù)庫連接池模塊,使得上層應(yīng)用通過本連接池訪問數(shù)據(jù) 庫資源變得相對高效和容易,從實際上論證了這種設(shè)計方案的可行性。 關(guān)鍵詞關(guān)鍵詞:連接池;數(shù)據(jù)庫;jdbc;并發(fā)訪問 research and realization of the database connection pool abstract in the practically application development of database based on jdbc, the management of database connection is a key point and also a difficulty. the response and performance of the web system are depended on frequently connecting, closing and multi-user accessing in a certain extent. using the database connection pool can provide management and maintenance for connections of the database. the upper applications may access the database recourse via the database connection pool, in order to upgrade system performance and fully utilize the system recourse. this article summarizes some issues which are easily ignored in the application development of the database connection pool by the way of introducing and analyzing the basal working principles of the database connection pool ,comprehending the using actuality of the database connection pool on the popular web servers. besides, i established a comparatively highly effective policy of the connection pool management after having learned and comprehended key technique of implementing the connectivity pool, and actually had developed a database connection pool module under the guidance of that policy, causing the access of system resource by the upper applications via current connectivity pool becoming relatively highly effective and easy, demonstrated the feasibility of this design project in practice. key words: database connection pool; database; jdbc; concurrence access 目目 錄錄 論文總頁數(shù):22 頁 1引言.1 1.1課題背景 1 1.2連接池的主要作用 1 1.3目前流行的web服務(wù)器數(shù)據(jù)庫連接池方面使用現(xiàn)狀 .1 1.3.1dhcp 介紹.2 1.3.2poolman 介紹.2 1.3.3c3p0 介紹.2 1.3.4其他連接池(自寫連接池)2 2相關(guān)理論基礎(chǔ).3 2.1數(shù)據(jù)庫概述 3 2.2數(shù)據(jù)庫連接池的基本原理 3 2.3連接池中的關(guān)鍵技術(shù) 4 2.3.1連接池的分配與釋放4 2.3.2連接池的維護5 3系統(tǒng)總體設(shè)計思想及方案.5 3.1連接池中的關(guān)鍵類設(shè)計 6 3.2連接池中的管理機制 7 3.3實現(xiàn)一個連接池的其他問題 8 3.3.1事務(wù)處理8 3.3.2封裝9 3.3.3并發(fā)9 3.3.4連接池的關(guān)閉9 4具體的設(shè)計流程和實現(xiàn).10 4.1連接池的建立 10 4.2連接池的管理 12 4.3連接池的關(guān)閉 14 4.4連接池的測試 15 5系統(tǒng)測試問題總結(jié).15 5.1連接池的泄露問題 15 5.1.1產(chǎn)生現(xiàn)象15 5.1.2解決辦法16 5.2多數(shù)據(jù)庫服務(wù)器問題 17 結(jié) 論.19 參考文獻.20 致 謝.21 聲 明.22 第 1 頁 共 22 頁 1 1引言引言 1.11.1 課題背景課題背景 隨著信息技術(shù)的高速發(fā)展與廣泛應(yīng)用,數(shù)據(jù)庫技術(shù)在信息技術(shù)領(lǐng)域中的位 置越來越重要。傳統(tǒng)的開發(fā)模式是:首先在主程序(如 servlet、beans)中建立 數(shù)據(jù)庫連接;然后進行 sql 操作,對數(shù)據(jù)庫中的對象進行查詢、修改和刪除等; 最后斷開數(shù)據(jù)庫連接。使用這種開發(fā)模式,對于一個簡單的數(shù)據(jù)庫應(yīng)用,由于 數(shù)據(jù)庫的訪問不是很頻繁,只需要在訪問數(shù)據(jù)庫時創(chuàng)建一個連接,用完后就關(guān) 閉它,這樣做不會明顯增大系統(tǒng)的開銷。但是對于一個復(fù)雜的數(shù)據(jù)庫應(yīng)用,情 況就完全不同了,尤其是大型電子商務(wù)網(wǎng)站,同時可能有幾百人甚至幾千人在 線。在這種情況下,用戶操作頻繁的建立、關(guān)閉數(shù)據(jù)庫,會極大的降低系統(tǒng)的 性能,增大系統(tǒng)的開銷,迫使網(wǎng)站的響應(yīng)速度下降,嚴重的甚至?xí)斐煞?wù)器 的崩潰。針對這些突出問題,采用運行速度更快、數(shù)據(jù)庫訪問效率更高的數(shù)據(jù) 庫連接池技術(shù),以提高系統(tǒng)的運行效率將是至關(guān)重要的,因此本文提出了一種 基于數(shù)據(jù)庫連接池技術(shù)的有效解決方法。以加強對數(shù)據(jù)庫操作的性能,改善資 源使用率,提高應(yīng)用程序的響應(yīng)能力。 1.21.2 連接池的主要作用連接池的主要作用 一個應(yīng)用系統(tǒng),同時有幾百人甚至幾千人頻繁的進行數(shù)據(jù)庫連接操作勢必 占用很多的系統(tǒng)資源,嚴重的甚至?xí)斐煞?wù)器的崩潰。對于每一次數(shù)據(jù)庫連 接,使用完后都得斷開。否則,如果程序出現(xiàn)異常而未能關(guān)閉,將會導(dǎo)致數(shù)據(jù) 庫系統(tǒng)中的內(nèi)存泄漏,最終將不得不重啟數(shù)據(jù)庫。還有,如果不能控制被創(chuàng)建 的連接對象數(shù),系統(tǒng)資源會被毫無顧及的分配出去,連接過多也可能導(dǎo)致內(nèi)存 泄漏,服務(wù)器崩潰。針對這些突出問題,因此提出了一種基于數(shù)據(jù)庫連接池技 術(shù)的有效解決方法。簡而言之,數(shù)據(jù)庫連接池主要作用是負責(zé)分配、管理和釋 放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不再是重 新建立一個;釋放空閑時間超過最大空閑時間的數(shù)據(jù)庫連接來避免因為沒有釋 放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏。 1.31.3 目前流行的目前流行的 web 服務(wù)器數(shù)據(jù)庫連接池方面使用現(xiàn)狀服務(wù)器數(shù)據(jù)庫連接池方面使用現(xiàn)狀 由于 jdbc 的 api 中沒有提供連接池的方法。一些大型的 web 應(yīng)用服務(wù)器如 weblogic、websphere 等都自帶有連接池。不同的是,tomcat 并沒有自已開發(fā) 連接池,而是集成的 apache 的另外一個開源項目 dbcp 連接池。bea 的 weblogic 自身帶有一個連接池,這個連接池?zé)o法與 weblogic 分離,但是也必 須有其第三方的專用類方法支持連接池的用法,而不需要用戶再去寫一個連接 池。以下是一些第三方連接池: 第 2 頁 共 22 頁 .1 dhcpdhcp 介紹介紹 dbcp 應(yīng) apache 的 jakarta 組織開發(fā),是目前使用較為廣泛的一個連接池, 一是因為 tomcat 自帶的就是這個連接池,二是因為開源免費。由于其使用的穩(wěn) 定性不是很好,著名的開源項目 hibernate 不再提供對它的支持。dbcp 部分參 數(shù)說明如下: datasource:要連接的 datasource (通常我們不會定義在 server.xml)。 defaultautocommit:對于事務(wù)是否 autocommit, 默認值為 true。 defaultreadonly:對于數(shù)據(jù)庫是否只能讀取, 默認值為 false。 driverclassname:連接數(shù)據(jù)庫所用的 jdbc driver class。 maxactive:最大連接數(shù)據(jù)庫連接數(shù),設(shè) 0 為沒有限制。 maxidle:最大等待連接中的數(shù)量,設(shè) 0 為沒有限制。 maxwait:最大等待秒數(shù), 單位為 ms, 超過時間會出錯誤信息。 password:登陸數(shù)據(jù)庫所用的密碼。 url:連接數(shù)據(jù)庫的 url。 username:登陸數(shù)據(jù)庫所用的帳號。 validationquery:驗證連接是否成功, sql select 指令至少要返回一行。 removeabandoned:是否自我中斷, 默認是 false。 removeabandonedtimeout:幾秒后會自我中斷, removeabandoned 必須為 true。 logabandoned:是否記錄中斷事件, 默認為 false。 .2 poolmanpoolman 介紹介紹 poolman 連接池前幾年應(yīng)用較廣泛,現(xiàn)在應(yīng)用相對較少。配置步驟主要是 先在/項目名稱/web-inf/下加入一個 jar 包,然后配置一個 xml 文件,文件屬 性類似于 dbcp,最后在程序中寫出調(diào)用該連接池的方法。 .3 c3p0c3p0 介紹介紹 c3p0 是一個開放源代碼的 jdbc 連接池,它在 lib 目錄中與 hibernate 一 起發(fā)布,包括了實現(xiàn) jdbc3.0 和 jdbc2.0 擴展規(guī)范說明的 connection 和 statement 池的 datasource 對象。 自從 hibernate 自帶了 c3p0 以后,c3p0 很快就受到了廣大程序員的認可, 其性能上來說比 dbcp 要好的多。 .4 其他連接池(自寫連接池)其他連接池(自寫連接池) 有些程序員喜歡自己寫連接池,建議不用這樣的方法,因為連接池的管理 第 3 頁 共 22 頁 較為復(fù)雜,自己寫常出現(xiàn)各種各樣的錯誤,推薦使用有成熟技術(shù)的連接池,同 時也方便系統(tǒng)的移植。 2 2相關(guān)理論基礎(chǔ)相關(guān)理論基礎(chǔ) 2.12.1 數(shù)據(jù)庫概述數(shù)據(jù)庫概述 數(shù)據(jù)庫,顧名思義,是存入數(shù)據(jù)的倉庫。只不過這個倉庫是在計算機存儲 設(shè)備上的,而且數(shù)據(jù)是按一定格式存放的。 當人們收集了大量的數(shù)據(jù)后,應(yīng)該把它們保存起來進入近一步的處理,進 一步的抽取有用的信息。當年人們把數(shù)據(jù)存放在文件柜中,可現(xiàn)在隨著社會的 發(fā)展,數(shù)據(jù)量急劇增長,現(xiàn)在人們就借助計算機和數(shù)據(jù)庫技術(shù)科學(xué)的保存大量 的數(shù)據(jù),以便能更好的利用這些數(shù)據(jù)資源。 要是下定義的話,就應(yīng)該是:指長期儲存在計算機內(nèi)的、有組織的、可共 享的數(shù)據(jù)集合。 數(shù)據(jù)庫包含關(guān)系數(shù)據(jù)庫、面向?qū)ο髷?shù)據(jù)庫及新興的 xml 數(shù)據(jù)庫等多種,目 前應(yīng)用最廣泛的是關(guān)系數(shù)據(jù)庫,若在關(guān)系數(shù)據(jù)庫基礎(chǔ)上提供部分面向?qū)ο髷?shù)據(jù) 庫功能的對象關(guān)系數(shù)據(jù)庫。在數(shù)據(jù)庫技術(shù)的早期還曾經(jīng)流行過層次數(shù)據(jù)庫與網(wǎng) 狀數(shù)據(jù)庫,但這兩類數(shù)據(jù)庫目前已經(jīng)極少使用。 2.22.2 數(shù)據(jù)庫連接池的基本原理數(shù)據(jù)庫連接池的基本原理 建立“緩沖存儲池” ,是數(shù)據(jù)庫連接池的基本設(shè)計思想。這種技術(shù)類似于 cpu 中的 cache 技術(shù),將預(yù)先設(shè)定好的數(shù)據(jù)庫連接放入該緩沖池中,當要建立 數(shù)據(jù)庫連接操作時,便從池中取出一個連接,使用完畢后再將其放回。這樣就 達到了連接復(fù)用的目的,應(yīng)用程序重復(fù)使用一個數(shù)據(jù)庫連接,在多層結(jié)構(gòu)的應(yīng) 用程序中通過連接池技術(shù)可以使系統(tǒng)的性能明顯得到提到。最為關(guān)鍵的是,該 方法避免了對數(shù)據(jù)庫連接的頻繁建立、關(guān)閉,減小了系統(tǒng)開銷,提高了響應(yīng)速 度。我們可以通過設(shè)定連接池最大連接數(shù)來防止系統(tǒng)無盡的與數(shù)據(jù)庫連接。更 為重要的是我們可以通過連接池的管理機制監(jiān)視數(shù)據(jù)庫的連接的數(shù)量使用情 況,為系統(tǒng)開發(fā)測試及性能調(diào)整提供依據(jù)。數(shù)據(jù)庫連接池屬于應(yīng)用程序?qū)Φ?層的調(diào)用,用戶并發(fā)訪問應(yīng)用程序時會提交訪問請求,然后通過線程來處理這 些請求,并向連接池申請一個對數(shù)據(jù)庫操作的連接,操作完畢后將連接釋放。 應(yīng)用程序調(diào)用連接池連接的基本工作原理如下圖所示: 第 4 頁 共 22 頁 圖 1 連接池的調(diào)用 基于以上原理,連接池的建立會在后面章節(jié)中做具體描述。為了方便理解, 連接池以 jsp 頁面形式將最大連接數(shù)的設(shè)置、連接池的使用、超時等待、連接 池的關(guān)閉等情況展示出來,給用戶一個更為直觀的感受。連接的調(diào)用原理如下 圖所示: 圖 2 建立數(shù)據(jù)庫連接 從圖中可以看出,當程序(jsp、servlet、javabean)中需要數(shù)據(jù)庫連接 時,只需從內(nèi)存中取出一個來,并將這個取得的連接加入 vector 中,而不用新 建連接;使用完畢后放回內(nèi)存中,并將 vector 中的已用連接刪除。 2.32.3 連接池中的關(guān)鍵技術(shù)連接池中的關(guān)鍵技術(shù) .1 連接池的分配與釋放連接池的分配與釋放 連接池的分配與釋放技術(shù)對系統(tǒng)的性能有很大的影響。合理的分配與釋放, 可以提高連接的復(fù)用度,從而降低建立新連接的開銷,同時還可以加快用戶的 訪問速度。對于連接的管理。每當用戶請求一個連接時,系統(tǒng)首先檢查連接池 內(nèi)有沒有空閑連接。如果有就把建立時間最長(通過容器的順序存放實現(xiàn))的 那個連接分配給他(實際是先做連接是否有效的判斷,如果可用就分配給用戶, 若不可用就把這個連接刪掉,重新檢測是否還有連接) ;如果檢查到當前所開連 接池沒有達到連接池所允許的最大連接數(shù)(maxconn),就新建一個連接,如果 已經(jīng)達到,就等待一定的時間(timeout) 。如果在等待的時間內(nèi)有連接被釋放 取得連接 釋放連接 第 5 頁 共 22 頁 出來就可以把這個連接分配給等待的用戶,如果等待時間超過預(yù)定時間 timeout,則返回空值(null) 。系統(tǒng)對已經(jīng)分配出去正在使用的連接只做計數(shù)。 .2 連接池的維護連接池的維護 數(shù)據(jù)庫連接池到底要放置多少個連接,這是個配置策略。為了使系統(tǒng)的性 能達到最佳狀態(tài),連接池中的連接數(shù)的設(shè)定顯得尤為重要,我們采用設(shè)置最大 連接數(shù)(maxconn)和最小連接數(shù)(minconn)的方式來解決這一問題。所謂最 大連接數(shù),即連接池中允許連接的最大數(shù)目,然后,最大連接數(shù)的設(shè)定要通過 具體的應(yīng)用需求來給出一個連接池可以承受的最大連接數(shù)目的最佳點。如果應(yīng) 用程序向連接池請求的連接數(shù)超過最大連接數(shù)量時,這些請求將被加入到等待 隊列中,等待其他連接的釋放后再來調(diào)用一空閑連接(freeconn) ,這樣可能會 影響部分對數(shù)據(jù)庫的操作。所謂最小連接數(shù),即應(yīng)用啟動前,已經(jīng)預(yù)先創(chuàng)建好 的連接數(shù)。無論這些數(shù)據(jù)庫連接是否被使用,連接池都將一直保證至少擁有這 么多的連接數(shù)量。如果最小連接數(shù)過大,那么系統(tǒng)啟動過程將變慢,若應(yīng)用程 序?qū)?shù)據(jù)庫的訪問量不大,過多的數(shù)據(jù)庫連接資源將被浪費,但是系統(tǒng)啟動后 響應(yīng)更快;如果過小系統(tǒng)啟動將加快,但是最初使用的用戶會因為連接池中沒 有足夠的連接而會發(fā)送一個新的數(shù)據(jù)庫連接請求,將不可避免的延緩執(zhí)行速度。 3 3系統(tǒng)總體設(shè)計思想及方案系統(tǒng)總體設(shè)計思想及方案 數(shù)據(jù)庫連接池技術(shù)的設(shè)計思想非常簡單,先將數(shù)據(jù)庫連接作為對象存儲在 一個 vector 對象中,vector 類可以實現(xiàn)可增長的對象“數(shù)組” 。vector 的大 小可以根據(jù)需要增大或縮小,以適應(yīng)創(chuàng)建 vector 后進行添加或移除項的操作。 這里主要包含使用的連接(nowconnections)和未使用的連接 (freeconnections)兩個 vector 類創(chuàng)建的對象,創(chuàng)建 vector 對象的方法如下: public dbconnectionpool(vector connections) freeconnections = new vector(); nowconnections = new vector(); 當外部程序向數(shù)據(jù)庫申請建立連接后,系統(tǒng)會調(diào)用 nowconnections.add( )方 法,此時已用連接計數(shù)器加 1,相應(yīng)的,調(diào)用 freeconnections.remove( )方法, 此時空閑連接計數(shù)器減 1,對于這樣的引用計數(shù)法將會在后面的章節(jié)中具體描 述。這樣,不同的數(shù)據(jù)庫訪問請求就可以共享這些連接,并通過復(fù)用這些已經(jīng) 建立的數(shù)據(jù)庫連接,克服傳統(tǒng)開發(fā)模式對數(shù)據(jù)庫操作的缺點。另外,采用超時 第 6 頁 共 22 頁 判斷(timeout)機制,等待應(yīng)用程序?qū)B接的釋放或者調(diào)用 connection.close()方法主動釋放連接,能極大地節(jié)省系統(tǒng)資源和用戶等待 時間。而實現(xiàn)連接池時,當應(yīng)用程序調(diào)用 connection.close( )試圖去關(guān)閉數(shù) 據(jù)庫連接時,這時需要有一個通告給連接池實現(xiàn)模塊,通告對當前的數(shù)據(jù)庫物 理連接(dbconnectionpool 對象)進行重用。為了使連接池實現(xiàn)模塊能得到這 種“通告” ,連接池實現(xiàn)模塊必須實現(xiàn) connectioneventlistener 接口,而且同 時需要注冊成為 dbconnectionpool 對象的監(jiān)聽者。連接池實現(xiàn)模塊接受到此通 告后,不是真正意義上的物理關(guān)閉,而是將 dbconnectionpool 對象返回到池中 進行重用。從上面的介紹,可以看出連接池技術(shù)的關(guān)鍵就是其自身的管理機制, 結(jié)合連接池工作的基本原理,通過下圖展現(xiàn)出一個連接池系統(tǒng)的總體設(shè)計框架。 圖 3 總體設(shè)計框架 建立數(shù)據(jù)庫連建立數(shù)據(jù)庫連 接 getconnection() closeconnection() 第 7 頁 共 22 頁 3.13.1 連接池中的關(guān)鍵類設(shè)計連接池中的關(guān)鍵類設(shè)計 一個連接池應(yīng)用的設(shè)計,需要幾個關(guān)鍵部分作為支撐,其中最為重要的是 dbconnectionpool 類和 dbconnectionmanager 類,他們對連接的建立、管理、 釋放起決定性作用。大體作用列舉如下: 1、一個 dbconnectionpool 類,該類負責(zé)從連接池獲取(或創(chuàng)建)連接、將 連接返回給連接池、空閑連接的超時等待、系統(tǒng)關(guān)閉時釋放所有資源并關(guān)閉所 有連接。 2、一個 datasourceproviderservlet 類,該類負責(zé)通過上下文環(huán)境讀取配 置文件后裝載和注冊 jdbc 驅(qū)動、數(shù)據(jù)庫名等。 3、一個 dbconnectionmanager 類,該類負責(zé)按預(yù)先指定的最大連接池數(shù)連 初始化連接池、創(chuàng)建 dbconnectionpool 對象 provider、當所有的連接客戶退 出后,關(guān)閉全部連接。 4、dbperties 屬性文件,該文件中包含了數(shù)據(jù)庫驅(qū)動 (drivername) 、數(shù)據(jù)庫 url、數(shù)據(jù)庫表空間名(user) 、表空間密碼 (password) 、連接池最大連接數(shù)(maxconnections) 。 5、即為應(yīng)用程序?qū)B接池中的連接的調(diào)用和釋放,應(yīng)用程序退出后連接池 的關(guān)閉。 將以上 5 個部分串連起來,即是本連接池的簡單設(shè)計流程。首先應(yīng)用程序 向連接池申請連接,就需要通過 dbconnectionpool 類、dbconnectionmanager 類對連接池初始化,并且還需要 datasourceproviderservlet 類的幫助讀取 dbperties 文件中的屬性,加載和注冊 jdbc 驅(qū)動、數(shù)據(jù)庫名等,連 接池才能初始化成功。之后通過 dbconnectionpool 類監(jiān)視、管理應(yīng)用程序調(diào)用、 釋放的數(shù)據(jù)庫連接,并通過該類的 cp 對象將連接使用情況反映在頁面上。連接 池管理程序得到某個連接,而其他線程就不會得到這個數(shù)據(jù)庫連接了,此線程 使用結(jié)束后,該線程將連接交還給連接池管理程序,以分配給其他等待連接的 請求線程。這里連接池充分利用 java 的線程同步機理,使當前服務(wù)線程處于等 待狀態(tài),直至有空閑的連接出現(xiàn)。最后當應(yīng)用程序退出時,通過 dbconnectionmanager 類負責(zé)連接池的關(guān)閉。 3.23.2 連接池中的管理機制連接池中的管理機制 應(yīng)用程序開發(fā)中“三分技術(shù)、七分管理”的思想在連接池的配置中同樣得 以體現(xiàn),如何從連接池中取得連接,何時釋放連接、如何釋放連接等問題還需 要為連接池配置更為復(fù)雜的管理機制,連接池流程的管理如下圖所示,這些屬 性定義了連接池與其中每個連接的有效狀態(tài)值。連接池的自我管理,實際上就 是通過定時的對每個連接的狀態(tài)、連接的數(shù)量進行判斷而進行相應(yīng)操作。 第 8 頁 共 22 頁 圖 4 連接池的管理 .1 事務(wù)處理事務(wù)處理 前面討論的是關(guān)于使用數(shù)據(jù)庫連接進行普通的數(shù)據(jù)庫訪問。對于事務(wù)處理, 情況就變得比較復(fù)雜。因為事務(wù)本身要求原則性的保證,此時就要求對于數(shù)據(jù) 庫的操作符合要么全部完成,要么什么都不做。如果簡單的采用上述的連接復(fù) 用的策略,就會發(fā)生問題,因為沒有辦法控制屬于同一個事務(wù)的多個數(shù)據(jù)庫操 作方法的動作,可能這些數(shù)據(jù)庫操作是在多個連接上進行的,并且這些連接可 能被其他非事務(wù)方法復(fù)用。connection 本身具有提供了對于事務(wù)的支持,可以 通過設(shè)置 connection 的 autocommit 屬性為 false,顯式的調(diào)用 commit 或 rollback 方法來實現(xiàn)。但是要安全、高效的進行連接復(fù)用,就必須提供相應(yīng)的 事務(wù)支持機制。方法是:采用顯式的事務(wù)支撐方法,每一個事務(wù)獨占一個連接。 這種方法可以大大降低對于事務(wù)處理的復(fù)雜性,并且又不會妨礙連接的復(fù)用。 定時觸發(fā)定時觸發(fā)單個連接狀態(tài)檢查完畢單個連接狀態(tài)檢查完畢 否 結(jié)束退出結(jié)束退出 第 9 頁 共 22 頁 連接管理服務(wù)提供了顯式的事務(wù)開始、結(jié)束(commit 或 rollback)聲明, 以及一個事務(wù)注冊表,用于登記事務(wù)發(fā)起者和事務(wù)使用的連接的對應(yīng)關(guān)系,通 過該表,使用事務(wù)的部分和連接管理部分就隔離開,因為該表是在運行時根據(jù) 實際的調(diào)用情況動態(tài)生成的。事務(wù)使用的連接在該事務(wù)運行中不能被復(fù)用。在 實現(xiàn)中,用戶標識是通過使用者所在的線程來標識的。后面的所有對于數(shù)據(jù)庫 的訪問都是通過查找該注冊表,使用已經(jīng)分配的連接來完成的。當事務(wù)結(jié)束時, 從注冊表中刪除相應(yīng)表項。 .2 封裝封裝 從上面的論述可以看出,普通的數(shù)據(jù)庫方法和事務(wù)方法對于連接的使用 (分配、釋放)是不同的,為了便于使用,對外提供一致的操作接口,對連接 進行了封裝:普通連接和事務(wù)連接,并利用了 java 中的強大的面向?qū)ο筇匦裕?多態(tài)。普通連接和事務(wù)連接均實現(xiàn)了一個 dbconnection 接口,對于接口中定義 的方法,分別根據(jù)自己的特點作了不同的實現(xiàn),這樣在對于連接的處理上就非 常的一致了。 .3 并發(fā)并發(fā) 為了使連接管理服務(wù)有更大的通用性,我們必須要考慮到多線程環(huán)境,即 并發(fā)問題。在一個多線程的環(huán)境下,必須要保證連接管理自身數(shù)據(jù)的一致性和 連接內(nèi)部數(shù)據(jù)的一致性,在這方面 java 提供很好的支持(synchronized 關(guān)鍵 字) ,這樣就很容易使連接管理成為線程安全的。 對于并發(fā)訪問,所有的當前請求都將被連接池管理程序按順序鎖定。對請 求線程的鎖定是通過應(yīng)用程序代碼進行的,且請求數(shù)量可以很大,不必擔(dān)心超 出緩沖容量限制。一旦將連接交還給連接池,該連接將由連接池管理程序分配 給其他鎖定的請求。當有很多數(shù)據(jù)庫請求并超出了連接池中連接的數(shù)目時,只 有先發(fā)出數(shù)據(jù)庫請求的線程獲得連接來訪問數(shù)據(jù)庫,其他連接暫時處于等待的 鎖定狀態(tài),當線程完成數(shù)據(jù)庫操作并釋放連接后,被釋放的連接將按順序由其 他線程獲得,這樣就可以大大節(jié)省服務(wù)器的資源。 .4 連接池的關(guān)閉連接池的關(guān)閉 很多的連接池都要求用戶通過其規(guī)定的方法獲取數(shù)據(jù)庫的連接,這一點我 們可以理解,畢竟目前所有的應(yīng)用服務(wù)器取數(shù)據(jù)庫連接的方式都是這種方式實 現(xiàn)的。但是另外一個共同的問題是,它們同時不允許使用者顯式的調(diào)用 connection.close()方法,而需要用其規(guī)定的一個方法來關(guān)閉連接。這種做法 有兩個缺點: 第 10 頁 共 22 頁 第一:改變了用戶使用習(xí)慣,增加了用戶的使用難度。使用者在用完數(shù)據(jù) 庫連接后通常是直接調(diào)用連接的 close 方法來釋放數(shù)據(jù)庫資源。 第二:使連接池?zé)o法對之中的所有連接進行獨占控制。由于連接池不允許 用戶直接調(diào)用連接的 close 方法,一旦使用者在使用的過程中由于習(xí)慣問題直 接關(guān)閉了數(shù)據(jù)庫連接,那么連接池將無法正常維護所有連接的狀態(tài)。 4 4具體的設(shè)計流程和實現(xiàn)具體的設(shè)計流程和實現(xiàn) 4.14.1 連接池的建立連接池的建立 應(yīng)用程序中建立的連接池其實是一個靜態(tài)的。所謂靜態(tài)連接池是指連接池 中的連接在系統(tǒng)初始化時就已分配好,且不能隨意關(guān)閉連接。java 中提供了很 多容器類可以方便的構(gòu)建連接池,如:vector、stack、servlet、bean 等,通 過讀取連接屬性文件 dbperties 與數(shù)據(jù)庫實例建立連接。(該屬性文 件中包含了連接數(shù)據(jù)庫的 url、數(shù)據(jù)庫驅(qū)動、數(shù)據(jù)庫表空間、數(shù)據(jù)庫表空間密 碼、連接池最大連接數(shù))在系統(tǒng)初始化時,根據(jù)相應(yīng)的配置創(chuàng)建連接并放置在連 接池中,這些對象作為系統(tǒng)可分配的自由連接,以后所使用的連接都是從連接 池中獲得,這樣就避免了隨意建立連接,關(guān)閉連接所帶來的資源浪費。 連接池初始化如下: public dbconnectionpool(vector connections) freeconnections = new vector(); nowconnections = new vector(); freeconnections = connections; maxconnections = freeconnections.size(); 本連接池的建立使用輸入流,通過上下文環(huán)境,讀取配置文件 (dbconfig.prooperties)里預(yù)先設(shè)置的參數(shù),部分代碼如下: public void contextinitialized(servletcontextevent event) properties ps = new properties(); vector connections = new vector(); servletcontext context = event.getservletcontext(); try /使用輸入流,讀取配置文件里的各種參數(shù) inputstream input = 第 11 頁 共 22 頁 getclass().getresourceasstream(“/dbperties“); ps.load(input); input.close(); url = (string) ps.get(“url“); user = (string) ps.get(“user“); password = (string) ps.get(“password“); drivername = (string) ps.get(“drivername“); maxconnections=integer.parseint(string) ps.get(“maxconnections“).trim(), 10); system.out.println(user); /循環(huán)加入取得的連接到 vector 中 for (int i = 0; i maxconnections; i+) /調(diào)用下面的方法,取得數(shù)據(jù)庫連接,并放入到 vector 中 connections.add(getconnection(url,user,password,drivername); catch (exception e) e.printstacktrace(); /放到服務(wù)器的上下文環(huán)境中 context.setattribute(“connector“,new dbconnectionpool(connections); 連接池初始化參數(shù)通過頁面設(shè)置寫入 dbperties 文件中,如下 圖所示: 第 12 頁 共 22 頁 圖 5 初始化連接池設(shè)置 4.24.2 連接池的管理連接池的管理 連接池管理策略是連接池機制的核心。當連接池建立后,如何對連接池中 的連接進行管理,解決好連接池內(nèi)連接的分配和釋放,對系統(tǒng)的性能有很大的 影響。連接的合理分配、釋放可提高連接的復(fù)用,降低了系統(tǒng)建立新連接的開 銷,同時也加速了用戶的訪問速度。下面介紹連接池中連接的分配、釋放策略。 連接池的分配、釋放策略對于有效復(fù)用連接非常重要。就一般情況而言, 當客戶釋放數(shù)據(jù)庫連接時,先判斷該連接的引用次數(shù)是否超過了規(guī)定值,如果 超過就刪除該連接,并判斷當前連接池內(nèi)總的連接數(shù)是否小于 minconn(最小 連接數(shù)) ,若小于就將連接池充滿;如果沒超過就將該連接標記為開放狀態(tài),可 供再次復(fù)用??梢钥闯稣沁@套策略保證了數(shù)據(jù)庫連接的有效復(fù)用,避免頻繁 地建立、釋放連接所帶來的系統(tǒng)資源開銷。我們采用的方法是一個很有名的設(shè) 計模式:reference counting(引用記數(shù)) 。該模式在復(fù)用資源方面應(yīng)用的非常 廣泛,把該方法運用到對于連接的分配釋放上,為每一個數(shù)據(jù)庫連接,保留一 個引用記數(shù),用來記錄該連接的使用者的個數(shù)。具體的實現(xiàn)方法是: public synchronized connection getconnection(int timeout) connection con = null; if (freeconnections.size() = 0) system.out.println(“連接失敗,由于數(shù)據(jù)庫連接池中無可 用連接!請等待!“); try new dbconnectionmanager().closeall(); 第 13 頁 共 22 頁 catch (exception ex) ex.printstacktrace(); return con; else connection temp = (connection) freeconnections.firstelement(); freeconnections.remove(temp); nowconnections.add(temp); return temp; 當應(yīng)用程序向數(shù)據(jù)庫發(fā)起連接請求時,會檢查連接池中是否存在空閑的連 接。如果存在空閑的連接,連接池則把空閑連接分配給客戶,并將該連接做相 應(yīng)處理,即標記為正在使用的連接,并將引用計數(shù)加 1。如果不存在空閑連接, 則檢查連接池里的連接數(shù)是否已經(jīng)達到了最大連接數(shù)(maxconn) ,若沒有達到 就為應(yīng)用程序創(chuàng)建一個新的連接;若達到了最大連接數(shù),那么就需要等待連接 的釋放,等待連接的釋放時間是由系統(tǒng)中預(yù)先定義好的一個超時參數(shù) (timeout)來做判斷。如果在超時等待(timeout)后仍沒有可用的空間連接, 程序上便會返回一個 null 值,同時拋出無空閑連接的異常給用戶。 public void timeout(int timeout, connection con) try thread t = new thread(); t.start(); t.run(); t.wait(timeout); closeconnection(con); t.destroy(); 第 14 頁 共 22 頁 catch (exception ex) ex.printstacktrace(); 已用連接計數(shù)器的問題交由 jsp 頁面中的循環(huán)來處理,每當應(yīng)用程序申請 一個連接時,計數(shù)器便會循環(huán)一次,部分實現(xiàn)代碼如下: for (int i = 0; i cp.getnowconnections().size(); i+) out.println(“連接名稱“ + (i + 1) + “:“ + cp.getnowconnections().get(i) + “); con = (connection)cp.getnowconnections().get(0); 對于未用連接的處理與已用連接類似,部分實現(xiàn)代碼如下: for (int j = 0; j cp.getfreeconnections().size(); j+) out.println(“未用連接名稱“ + (j + 1) + “:“ + cp.getfreeconnections().get(j) + “); 連接池的調(diào)用如下圖所示,若連接已分配完畢,系統(tǒng)提示等待連接釋放。 圖 6 連接的調(diào)用 第 15 頁 共 22 頁 4.34.3 連接池的關(guān)閉連接池的關(guān)閉 當應(yīng)用程序退出時,通過調(diào)用 closeall()方法來關(guān)閉連接池中的連接, 此時應(yīng)把在連接池建立時向數(shù)據(jù)庫申請的連接對象統(tǒng)一歸還給數(shù)據(jù)庫(即關(guān)閉 所有數(shù)據(jù)庫連接) 。 public void closeall() try if (rs != null) rs.close(); if (smt != null) smt.close(); if (psmt != null) psmt.close(); if (con != null) provider.closeconnection(con); catch (exception e) e.printstacktrace(); 4.44.4 連接池的測試連接池的測試 對于一個好的連接池,性能顯得尤為重要。性能不僅僅體現(xiàn)的是對數(shù)據(jù)庫 操作的處理速度還有連接池自身的穩(wěn)定性。通過壓力測試,對比能夠看出 dbcp 連接池要比 hibernate3.0 默認自帶的數(shù)據(jù)庫連接池 c3p0 快,但是穩(wěn)定性卻不 如它,并發(fā)用戶過多常常會自動斷開連接。通過對本連接池的測試發(fā)現(xiàn),有連 接池的時候?qū)?shù)據(jù)庫的操作要比沒有連接池的時候快 3-5 秒。 一般數(shù)據(jù)庫連接池采用 dbcp 作為連接池時,默認的初始化為 50 個,速度 不會有太大問題。正常情況下,系統(tǒng)沒問題,壓力測試從 10 個并發(fā)開始,每一 次增量是增加 10 個并發(fā),至 200-400 并發(fā)用戶將成為一個重要節(jié)點,性能的優(yōu) 越能得以體現(xiàn)。而本連接池沒有經(jīng)過壓力測試,多用戶的并發(fā)訪問時其穩(wěn)定性 還有待驗證。 5 5系統(tǒng)測試問題總結(jié)系統(tǒng)測試問題總結(jié) 5.15.1 連接池的泄露問題連接池的泄露問題 .1 產(chǎn)生現(xiàn)象產(chǎn)生現(xiàn)象 當系統(tǒng)訪問量較大時,會出現(xiàn)連接池連接數(shù)居高不下的情況,如果在關(guān)閉 數(shù)據(jù)庫連接的過程中發(fā)生錯誤會導(dǎo)致他們不再會被重用。這就叫做“數(shù)據(jù)庫連 第 16 頁 共 22 頁 接池泄漏” 。這將會最終導(dǎo)致 web 應(yīng)用程序數(shù)據(jù)庫連接失敗。甚至造成連接池崩 潰,從而無法進行數(shù)據(jù)交互,服務(wù)器當機。 .2 解決辦法解決辦法 常見的程序錯誤寫法有以下兩種: 1、當連接執(zhí)行數(shù)據(jù)庫操作出錯時,未執(zhí)行數(shù)據(jù)庫關(guān)閉。 connection conn = dbutil.getconnection(); ./執(zhí)行數(shù)據(jù)庫操作 dbutil.closeconnection(); 在以上代碼中,如果執(zhí)行數(shù)據(jù)庫操作過程中,出現(xiàn)異常,系統(tǒng)從出現(xiàn)異常 處停止,不再執(zhí)行下面的代碼,造成數(shù)據(jù)庫連接池?zé)o法回收,連接泄露的情況。 正確的代碼寫法應(yīng)如下: try connection conn = dbutil.getconnection(); ./執(zhí)行數(shù)據(jù)庫操作 catch(exception e) finally dbutil.closeconnection(); /異常處理后必須處理的方法。 這樣將保證了在執(zhí)行數(shù)據(jù)庫操作過程中即使出現(xiàn)異常,也將能夠執(zhí)行數(shù)據(jù) 庫連接池的回收。 2、在連接中嵌套數(shù)據(jù)庫連接,如下: try connection conn = dbutil.getconnection(); domethoda()/執(zhí)行數(shù)據(jù)庫操作 catch(exception e) finally 第 17 頁 共 22 頁 dbutil.closeconnection(); public void domethoda() ./再次打開數(shù)據(jù)庫進行操作 在上面的例子中,當調(diào)用方法 domethoda()時,在方法內(nèi)部又打開了一 個數(shù)據(jù)庫連接,這時造成同一線程中打開了兩個連接,如果不注意,很有可能 就打開了更多的連接,以至于成為系統(tǒng)性能的瓶頸。 5.25.2 多數(shù)據(jù)庫服務(wù)器問題多數(shù)據(jù)庫服務(wù)器問題 如今在一個應(yīng)用系統(tǒng)中,一般可能不只訪問一個數(shù)據(jù)庫,有時會訪問兩個 或是多個數(shù)據(jù)庫,各個數(shù)據(jù)庫的數(shù)據(jù)必須融會到同一個業(yè)務(wù)邏輯中,否則就成 為一個個低價值的數(shù)據(jù)孤島,這時就需用到多數(shù)據(jù)源。 在一個應(yīng)用系統(tǒng)中,一般會有一個數(shù)據(jù)源應(yīng)用較多,其它數(shù)據(jù)源應(yīng)用較少, 我們把應(yīng)用較多的數(shù)據(jù)源定義為主數(shù)據(jù)源,其它數(shù)據(jù)源定義為從數(shù)據(jù)源。 我們?yōu)槊恳粋€數(shù)據(jù)源定義一個名稱,在應(yīng)用系統(tǒng)中根據(jù)該名稱定向到數(shù)據(jù) 源。在應(yīng)用中,我們定義一個靜態(tài) hashtable 對數(shù)據(jù)源進行保存。下面給出一 個方法: /* * 數(shù)據(jù)源 hash 表 */ private static final hashtable dshash = new hashtable(); 用戶在調(diào)用數(shù)據(jù)源時,首先從 hash 中查詢該數(shù)據(jù)源,如果存在,直接返回, 如果不存在,則初始化 datasource,并放入 hash 中,再返回。注意:這兒用到 了同步,以防止同一數(shù)據(jù)源初始化兩次。 /* * 初始化 datasource * * param db_name */ private static synchronized datasource init(string db_name) datasource ds1 = (datasource) dshash.get(db_name); if (ds1 = null) 第 18 頁 共 22 頁 try context initctx = new initialcontext(); /從配置文件中讀取數(shù)據(jù)源,如果未配置,則用主數(shù)據(jù) 源 string s = configutil.getproperty(db_name, configutil.getproperty(“jndi_datasource“); object obj = (object) initctx.lookup(s); if (obj != null) ds1 = (javax.sql.datasource) obj; dshash.put(db_name, ds1); else system.out.println(“未找到數(shù)據(jù)源“); catch (exception ex) ex.printstacktrace(); dshash.remove(db_name); return ds1; /* * 根據(jù) jndi 名打開連接 * 打開該連接后應(yīng)該關(guān)閉 * 注:不能調(diào)用本類的方法 closeconnection 關(guān)閉連接,應(yīng)該在外部 用 conn.close()關(guān)閉 * * param db_name jndi 名稱 * return */ public static connection getconnections(string db_name) 第 19 頁 共 22 頁 if (db_name = null) return getconnection(); else connection conn = null; / jndi_name = pname; /從哈希表中查詢,如果不存在則創(chuàng)建 try conn = init(db_name).getconnection(); catch (sqlexception e) e.printstacktrace(); catch (exception e) e.printstacktrace(); return conn; /* * 關(guān)閉連接, * * param db_name * param conn1 */ public static void closeconnections(string db_name, connection conn1) if (db_name = null) closeconnection(); else closeconnections(conn1); 本系統(tǒng)并沒有針對多數(shù)據(jù)源的情況處理,以上只是將可能遇到的問題進行 歸納總結(jié),仍需要補充和完善。 第 20 頁 共 22 頁 結(jié)結(jié) 論論 通過本次課題的研究,可以看出在廣泛采用 b/s 結(jié)構(gòu)的 web 應(yīng)用程序中, 并發(fā)訪問數(shù)據(jù)庫是一關(guān)鍵性問題。只有充分運用連接池訪問技術(shù),才能提高數(shù) 據(jù)庫的訪問效率,改善 web 應(yīng)用,從而減少系統(tǒng)開銷。在進行與數(shù)據(jù)庫有關(guān)的 應(yīng)用開發(fā)中,數(shù)據(jù)庫連接的管理是一個重點,也是一個難點。很多時候,連接 的混亂管理所造成的系統(tǒng)資源開銷過大成為制約大型企業(yè)級應(yīng)用效率的瓶頸。 對于眾多用戶訪問的 web 應(yīng)用,采用數(shù)據(jù)庫連接技術(shù)的系統(tǒng)在效率和穩(wěn)定性上 比采用傳統(tǒng)的其他方式的系統(tǒng)要好很多。本文采用了一些廣泛使用的設(shè)計模式 (資源池,引用記數(shù)等) ,討論了基于連接池技術(shù)的數(shù)據(jù)庫連接管理的關(guān)鍵問題 并給出了一個實現(xiàn)模型。

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論