專利名稱:一種多線程應用程序訪問數(shù)據(jù)庫的方法
技術領域:
本發(fā)明涉及數(shù)據(jù)庫訪問技術領域,特別是指一種多線程應用程序訪問數(shù)據(jù)庫的方法。
背景技術:
JDBCTMAPI是Java程序與數(shù)據(jù)庫交互的一種應用程序接口,由一些Java語言編寫的類和界面組成,用以使Java應用程序向數(shù)據(jù)庫發(fā)送SQL語句以訪問數(shù)據(jù)庫。當然,要實現(xiàn)Java程序與數(shù)據(jù)庫通訊,還需要加載JDBC驅(qū)動程序(JDBC Driver)(驅(qū)動程序可由DBMS廠商、或第三方廠商提供)。當Java程序已經(jīng)加載了JDBC驅(qū)動后,就可以通過JDBC API提供的DriverManager類與數(shù)據(jù)庫建立訪問通道。
在訪問數(shù)據(jù)庫過程中,JDBC API通過其DriverManager.getConnection()函數(shù)獲得數(shù)據(jù)庫連接(Connection),一旦獲得了與數(shù)據(jù)庫的連接(Connection),Java應用程序就可以通過JDBC API向數(shù)據(jù)庫發(fā)送SQL語句,去檢索或者操作數(shù)據(jù)庫。
同時參見圖1示出的JDBC訪問數(shù)據(jù)庫的流程圖,下面的斜體字部分示出了JDBC使用命令對象(Statement對象)執(zhí)行數(shù)據(jù)庫查詢或者更新的基本邏輯//------調(diào)用getConnection()方法,獲得一個與數(shù)據(jù)庫的連接對象(Connection對象)------Connection con=DriverManager.getConnection()//------創(chuàng)建命令對象(Statement對象)并準備一個SQL語句,這里的SQL語句是被立即執(zhí)行的語句Statement對象------Statement stmt=con.createStatement()
/*查詢SQL命令例子,其中aSQL是一個數(shù)據(jù)庫查詢命令*///------使用Statement對象執(zhí)行查詢qurey語句(為了執(zhí)行Statement對象,被發(fā)送到數(shù)據(jù)庫的SQL語句aSQL將作為參數(shù)提供給Statement對象),得到一個存儲結(jié)果的ResultSet對象ResultSet results=prepStmt.executeQuery(aSQL)//-----從ResultSet讀取數(shù)據(jù),關閉該對象接口------results. close()/*更新SQL命令例子,其中bSQL是一個數(shù)據(jù)庫更新命令*///------使用Statement對象執(zhí)行更新update語句------int rowsAffected=prepStmt.execute Update(bSQL)//------關閉Statement對象接口------stmt.close()//------關閉連接------con.close()上面的例子中,使用Statement對象(命令的對象)執(zhí)行SQL命令,SQL命令由數(shù)據(jù)庫側(cè)DBMS(數(shù)據(jù)庫管理系統(tǒng))接收后,執(zhí)行該SQL命令時,DBMS要進行以下的步驟第一步驟解析接受到的SQL語句;第二步驟編譯此SQL語句;第三步驟計劃和優(yōu)化數(shù)據(jù)獲取的路徑;第四步驟執(zhí)行SQL命令并返回結(jié)果給請求端Statement對象。
使用Statement對象實現(xiàn)數(shù)據(jù)庫的訪問的缺點是,當出現(xiàn)Statement對象執(zhí)行SQL的命令被數(shù)據(jù)庫DBMS再次調(diào)用時,DBMS還會重復上面的四個步驟,重復的解析、編譯過程大大影響了訪問數(shù)據(jù)庫的性能。
為了解決上述問題,在Statement對象接口技術的基礎上發(fā)展出PreparedStatement對象(準備好的命令對象)接口技術。PreparedStatement對象包含已編譯的SQL語句,這就是使語句“準備好”。包含于PreparedStatement對象中的SQL語句可具有一個或多個IN參數(shù)。由于PreparedStatement對象已預編譯過,所以其執(zhí)行速度要快于Statement對象。
使用該技術,上面所述的DBMS所執(zhí)行的前三步驟可以進行優(yōu)化或者省略掉。同時參見圖1示出的JDBC訪問數(shù)據(jù)庫的流程圖,下面斜體字示出了JDBC一個使用PreparedStatement對象執(zhí)行數(shù)據(jù)庫查詢或者更新的基本邏輯//------調(diào)用getConnection()方法,獲得一個與數(shù)據(jù)庫的連接對象(Connection對象)-----Connection con=DriverManager.getConnection()//------創(chuàng)建命令對象(Statement對象)并準備一個SQL語句,這里的SQL語句是被編譯的語句PreparedStatement對象-----PreparedStatement prepStmt=con.prepareStatement(aSQL)prepStmt.setInt(1,integerParam)prepStmt.setString(2,stringParam)/*查詢SQL命令例子,其中aSQL是一個數(shù)據(jù)庫查詢命令*/ResultSet results=prepStmt.executeQuery(aSQL)//-----從ResultSet讀取數(shù)據(jù)------results.close()/*更新SQL命令例子,其中bSQL是一個數(shù)據(jù)庫更新命令*/int rowsAffected=prepStmt.execute Update(bSQL)prepStmt.close()con.close()采用PreparedStatement對象技術實現(xiàn)上述優(yōu)點來提高數(shù)據(jù)庫訪問的性能的關鍵技術其中之一是采用了連接池的策略。下面對目前采用的兩種連接池技術進行具體說明。
1、緩存Connection的連接池連接池用來緩存Connection對象,使用連接池,緩存入池中的Connection僅需創(chuàng)建一次,之后會得到重用,可避免重復創(chuàng)建連接所耗費的時間和資源。
目前,DBMS廠商提供了JDBC API的DataSource和PooledConnection/XAConnection接口,可從這些接口中獲得Connection并緩存到連接池。其中DataSource接口對象是典型的通過JNDI服務獲取的實例。還包括如下示出的獲得Connection的接口a、ConnectionPoolDataSource對象,可基于連接請求提供PooledConnection連接對象;b、XADataSource對象,可基于連接請求提供XAConnection連接對象。
連接池可以通過預先與DBMS建立連接的方式建立(稱之為熱連接)或者向數(shù)據(jù)庫發(fā)出第一個請求的時候建立(稱之為懶連接),甚至兩種方式結(jié)合獲取(先獲取部分熱連接,當獲取后續(xù)連接的平均時間增加的時候,繼續(xù)用懶連接的方式創(chuàng)建連接并緩沖到內(nèi)區(qū))。
2、緩存Connection和PreparedStatement對象的連接池不管PreparedStatement對象被應用程序在何時創(chuàng)建,都隨同Connection一起緩存到連接池。這樣,當PreparedStatement對象執(zhí)行aSQL的命令被數(shù)據(jù)庫DBMS再次調(diào)用時,與Connection一起緩沖到內(nèi)存的編譯后的PreparedStatement對象也可以連同Connection被應用程序再次使用,相對于僅連接的池化來說,進一步的,DBMS不需要重復解析SQL的步驟了。
但是,目前使用所述連接池訪問數(shù)據(jù)庫的方式還是存在著如下的缺點1、對于多線程應用程序,如果每個線程都從連接池獲取Connection并執(zhí)行一個SQL命令,那么此Connection直到被第一個使用的線程執(zhí)行完SQL命令并返回值將該Connection和PreparedStatement對象釋放回連接池后,該Connection和PreparedStatement對象才能被其他的線程使用。也就是說,在任意時刻一個Connection和PreparedStatement對象只能被一個線程使用,否則可能出現(xiàn)一個線程在發(fā)送一個查詢而另一個線程正在接受結(jié)果,而導致訪問數(shù)據(jù)庫的混亂。
從另一個角度來看,在數(shù)據(jù)庫連接上執(zhí)行SQL命令的時候,此Connection會被此線程獨占,對于其他線程來說,若同時請求獲得該Connection時,其現(xiàn)象是調(diào)用該Connection發(fā)生阻塞,即不被允許調(diào)用,從而造成數(shù)據(jù)庫訪問性能的降低。即使是JDBC 3.0中也沒有給出解決多線程同時訪問數(shù)據(jù)庫阻塞的方案。
2、對于大多數(shù)的應用程序的數(shù)據(jù)訪問,不同的PreparedStatement對象的被執(zhí)行次數(shù)也是不同的,一些命令可能被頻繁執(zhí)行,而有些命令很少被執(zhí)行,甚至很有可能被執(zhí)行的就那么一次而已,因此應用程序要求已池化的PreparedStatement對象個數(shù)應該依賴于或者取決于SQL命令被執(zhí)行的次數(shù)。但是,上述方案中,與Connection一起緩存在連接池中的PreparedStatement對象的個數(shù)在大多數(shù)情況下是不可配置的,故無法根據(jù)不同應用程序訪問情況進行調(diào)整,從而導致連接池中緩存的PreparedStatement對象個數(shù)難以做到負載均衡。
發(fā)明內(nèi)容
有鑒于此,本發(fā)明的主要目的在于提供了一種多線程應用程序訪問數(shù)據(jù)庫的方法,以解決多線程程序通過JDBC API訪問數(shù)據(jù)庫阻塞問題,以提高數(shù)據(jù)庫訪問性能。
實現(xiàn)本發(fā)明所述的多線程應用程序訪問數(shù)據(jù)庫的方法,需要預先建立到數(shù)據(jù)庫的不同的連接并進行緩存,并分別在所述不同連接里建立要使用的命令對象并緩存入命令池,當某個線程調(diào)用某連接和該連接上的命令對象訪問數(shù)據(jù)庫時,包括以下步驟A、判斷命令池中是否有未被調(diào)用的所述命令對象,若有,則執(zhí)行下一步,否則選擇一個連接并在該連接上建立所述命令對象;B、選擇所述的命令對象和該命令對象所屬的連接;C、所述線程調(diào)用所選擇的連接和命令對象訪問數(shù)據(jù)庫。
其中,所述分別在不同連接里建立要使用的命令對象的步驟包括從配置文件或者數(shù)據(jù)庫配置項表中讀取命令池的配置信息來構(gòu)建命令池;所述配置信息包括要創(chuàng)建所述命令對象的數(shù)量;獲取連接對象,根據(jù)所述配置信息依次在不同的連接對象上創(chuàng)建所述的命令對象。
其中,所述配置信息更改時,讀取更新的配置信息更新命令池的配置。
其中,該方法進一步包括對命令池中的各個命令對象的調(diào)用的頻率進行統(tǒng)計,在特定的周期內(nèi)刪除命令池中被調(diào)用頻率低的命令對象。
其中,在線程結(jié)束調(diào)用所述連接和命令對象時,進一步包括該線程釋放命令對象和所述的連接的步驟。
其中,取消使用所述命令池時,進一步包括銷毀所述命令池的步驟。
其中,所述的命令對象為PreparedStatement對象。
由上述方法可以看出,本發(fā)明為每一個SQL命令提供一種獨立于連接池的PreparedStatement命令對象緩沖池,在各個連接上均建立相應的PreparedStatement命令對象,從而避免某連接被占用而無法調(diào)用該PreparedStatement命令對象導致的不能訪問數(shù)據(jù)庫,解決了Java多線程應用程序訪問數(shù)據(jù)庫的阻塞問題。實現(xiàn)無事務操作且參數(shù)化的動態(tài)的SQL命令的無阻塞的需求。
另一方面,每一個SQL命令對應的PreparedStatement對象池的緩沖大小可配置,即緩存的PreparedStatement對象的個數(shù)可配置,并且根據(jù)被執(zhí)行的SQL命令的頻率動態(tài)調(diào)整PreparedStatement對象的個數(shù),實現(xiàn)提供負載均衡。實現(xiàn)了在已建立的數(shù)據(jù)庫連接上發(fā)出SQL命令的負載均衡。
圖1為JDBC訪問數(shù)據(jù)庫的示意圖。
圖2為本發(fā)明PreparedStatement對象池的示意圖。
圖3為本發(fā)明訪問數(shù)據(jù)庫流程圖。
圖4為PreparedStatement對象池的建立、使用以及銷毀流程圖。
具體實施例方式
對于背景技術所述的連接池技術訪問數(shù)據(jù)庫,當出現(xiàn)多線程訪問數(shù)據(jù)庫時出現(xiàn)的阻塞問題,可以理解為從某個單一的Connection上生成PreparedStatement對象,然后多線程并發(fā)訪問該PreparedStatement對象,就如獨木橋上的行人,只能排隊過橋,因此引起了多線程并發(fā)訪問數(shù)據(jù)庫的阻塞。
本發(fā)明的實現(xiàn)機制是這樣的根據(jù)實際的應用情況,預先生成多個數(shù)據(jù)庫連接(Connection),然后在不同的Connection上生成多個PreparedStatement對象,使得每個Connection上都有實現(xiàn)相同功能的PreparedStatement對象,然后把不同的PreparedStatement對象放入命令池(緩存區(qū)),不同的線程從池中獲取的PreparedStatement對象時是從不同的Connection上獲取的PreparedStatement對象,從而實現(xiàn)了線程的并發(fā)訪問。如果在同一個堤口上架設了多度橋梁為多個行人服務。
下面對本發(fā)明所述的多線程應用程序訪問數(shù)據(jù)庫的方法進行說明。
預先,要初始化建立不同的Connection,以及在不同的Connection上建立要使用的PreparedStatement對象,并將所建立的PreparedStatement對象和Connection緩存入命令池。
如圖2示出了本發(fā)明所建立的存放PreparedStatement對象的命令池的示意圖,在池中緩存有不同的Connection,對于每個不同的Connection,又分配有不同個數(shù)的PreparedStatement對象。如圖,圖中的連接對象C1、C2、C3以及C4是所緩存的到數(shù)據(jù)庫的連接,對于每一個連接,分別擁有緩存的PreparedStatement對象S1、S2、S3以及S4。命令對象池內(nèi)的對應每一個SQL命令的PreparedStatement對象的個數(shù)可以在配置文件中或者數(shù)據(jù)庫的配置項表格中進行配置。
參見圖3,在初始化好上述命令池后,當某個線程訪問數(shù)據(jù)庫時,包括以下步驟
步驟301判斷命令池中是否有未被調(diào)用的所述PreparedStatement對象,有,則下一步,否則在一Connection上建立所述PreparedStatement對象;步驟302選擇該PreparedStatement對象、該PreparedStatement對象所屬的Connection;步驟303該線程調(diào)用所選擇的Connection和PreparedStatement對象訪問數(shù)據(jù)庫;步驟304在結(jié)束該調(diào)用時,釋放PreparedStatement對象回命令池,結(jié)束。
另外,還可以對每個Connection中的PreparedStatement對象的個數(shù)進行動態(tài)調(diào)整,例如,對于預先建立的PreparedStatement對象或者是在步驟301中建立的PreparedStatement對象,可以對各個PreparedStatement對象的調(diào)用的頻率進行統(tǒng)計,并在特定的周期內(nèi)刪除命令池中被調(diào)用頻率低的PreparedStatement對象,以保證在必要的時刻有足夠的空間建立新的PreparedStatement對象。
下面,對本發(fā)明的各個步驟進行詳細的描述,來說明本發(fā)明是如何實現(xiàn)的。參照圖4示出的緩存PreparedStatement對象的命令池的建立、使用以及銷毀流程圖,進行說明步驟401~403示出了命令池的初始化過程當應用程序啟動的時候,命令池初始化模塊首先獲取一定數(shù)量的數(shù)據(jù)庫連接(Connection),并從配置文件或者數(shù)據(jù)庫配置項表中讀取命令池的配置信息并傳遞給StatementPool對象去完成初始化工作。
一般地,考慮線程的并發(fā)數(shù)量和對應SQL命令的執(zhí)行時長,需要對命令池內(nèi)命令PreparedStatement對象的數(shù)量進行配置(相當于創(chuàng)建命令池的容量)。而這些配置信息的數(shù)據(jù)結(jié)構(gòu)是這樣的ID(SQL命令對象的標識),MIN(SQL命令在命令對象池的最小值),MAX(SQL命令在命令對象池的最大值),配置多個PreparedStatement對象來滿足多線程的并發(fā)訪問要求。其中MIN和MAX需要根據(jù)實際的使用場合進行配置,盡量考慮實際的應用場合的并發(fā)線程數(shù)量為MIN值,MAX值可以考慮為自增長模式的命令池使用,而自增長的生成機制和初始化命令池的機制是一樣的。
實際應用中,將上述配置信息放入配置文件(如寫入Config.txt),然后程序可以動態(tài)讀取配置文件,實現(xiàn)動態(tài)配置命令池。如下面的一種實現(xiàn)動態(tài)配置的機制設定配置文件Config.txt包含如下4條SQL命令的信息SQLID=1,MIN=4,MAX=4SQLID=2,MIN=4,MAX=4初始化時,啟動一個定時器,在指定的T時間讀取上述的配置文件Config.txt,如果是第一次讀取,則根據(jù)讀取的配置值完成命令池的構(gòu)建;如果已經(jīng)讀取過配置文件,則判斷跟前一次讀取的內(nèi)容和本次讀取的內(nèi)容是否一致,如果一致則不更新命令池;如果不一致,則根據(jù)讀取的Config.txt更新命令池的配置。
上面是命令池的初始化(相當于創(chuàng)建緩存區(qū)的容量),然后在獲取的Connection上創(chuàng)建PreparedStatement對象寫入命令池參見下面描述的初始化命令池的業(yè)務邏輯過程,如下第一步驟將調(diào)用者傳遞的初始化參數(shù)分配到不同的數(shù)據(jù)庫連接(Connection)。初始化所需的參數(shù)如下需要用來創(chuàng)建命令對象池的數(shù)據(jù)庫連接(Connection);每一種PreparedStatement對象的SQL語句字符串;每一種PreparedStatement對象的實例個數(shù)。
第二步驟根據(jù)所傳遞的初始化參數(shù),從不同的數(shù)據(jù)庫連接(Connection)上循環(huán)生成相應的PreparedStatement對象。
具體可如圖2所示,傳入C1、C2、C3和C4連接對象(C1、C2、C3、C4分別為不同的Connection對象)以及命令對象的大小為6。為了實現(xiàn)多線程訪問數(shù)據(jù)庫命令對象的負載均衡機制,先從C1上生成S1,繼續(xù)從C2、C3、C4上生成新的S1對象(S1、S2、S3和S4分別為不同的SQL命令對應的PreparedStatement對象,相同的PreparedStatement對象構(gòu)成命令隊列),然后循環(huán)到C1和C2上繼續(xù)創(chuàng)建剩下的兩個命令對象。類似的機制創(chuàng)建S2、S3和S4命令對象。這樣,形成了如圖2所示的命令池,此命令池分別使用4個Connection,在C1對象上有兩個S1對象、一個S2對象、兩個S3對象、一個S4對象;在C2對象上有兩個S1對象、一個S2對象、兩個S3對象、一個S4對象;在C3對象上有一個S1對象、兩個S2對象、兩個S3對象、一個S4對象;在C4對象上有一個S1對象、一個S2對象、兩個S3對象、一個S4對象。相當于S1、S2、S3和S3四個命令隊列分配在不同的連接對象上。
下面示出了初始化命令池的邏輯//-----初始化連接對象的指針------connectionPointer=0//-----生成不同命令對象的隊列------Queue[]statementQueue is a new Array of Queue objects//-----循環(huán)生成命令對象,循環(huán)次數(shù)為命令隊列配置的大小,由調(diào)用者傳入此參數(shù)------for statementIndex from 0 to numberOfSQLs-1//-----輪詢連接池,從不同的連接上生成命令對象------for cacheCount from 0 to aPStmtCountArray[statementIndex]-1//-----獲取連接對象的指針------connectionPointer=++connectionPointer%numOfConnections//-----從獲得的連接上生成命令對象------pStmt=aConnArray[connectionPointer].prepareStatement(aSQLArray[statementIndex])//-----把生成的命令對象放入到命令對列/命令池------statementQueue[statementIndex].add(pStmt)end for
end for需要指出的是StatementQueue假定是一個線程安全的FIFO(先進先出)存儲器,且支持并發(fā)訪問的數(shù)據(jù)結(jié)構(gòu)。而連接隊列被認為是創(chuàng)建命令緩沖池隊列的簡單循環(huán)隊列。
另一方面,若在請求調(diào)用的過程中,判斷如果已緩沖的PreparedStatement對象全部被應用程序使用,且應用邏輯請求一個新的PreparedStatement對象,那么必須在現(xiàn)存的基礎上繼續(xù)創(chuàng)建新的PreparedStatement對象并放入池內(nèi)以供新的請求使用,該創(chuàng)建的過程和初始化的過程相同。
初始化后,不同的命令對象(PreparedStatement對象)就分布在不同的連接(Connection)上,從而多線程程序在訪問PreparedStatement對象的時候,是從命令池中獲得命令對象,也就是說是從不同的Connection上完成SQL操作的,從而分擔了負荷。舉例來說,如果某個線程從圖2的命令池中獲取PreparedStatement對象完成相應的SQL操作,則首先會從C1的連接上獲取PreparedStatement對象來完成所述SQL操作,若此刻另外一個線程同時訪問命令池,則這種多線程的機制會分配C2連接給另一線程,不會與第一個線程同時在C1上完成操作,后續(xù)的線程進行數(shù)據(jù)庫訪問繼續(xù)在C3、C4、C1、C2這樣的循環(huán)機制上獲取PreparedStatement對象,從而實現(xiàn)了均衡負載以及數(shù)據(jù)庫訪問并發(fā)的效率的提升。
步驟404~408提供了某一線程從命令池中獲取PreparedStatement對象以用來訪問數(shù)據(jù)庫具體的實現(xiàn)方式。這幾個步驟是上述步驟301~302的具體的實現(xiàn)。
其中,需要傳入的參數(shù)是命令對象的索引(此索引與初始化池的時候的SQL數(shù)組的索引下標一致)。
從命令池的獲取命令接口的簡要程序邏輯如下//-----判斷命令池的使用情況,如果存在命令對象則從可使用的命令對象池重獲取命令對象,并返回給調(diào)用者------If statementQueue[statementIndex]is not emptyreturn statementQueue[statementIndex].remove()//-----如果池內(nèi)無可使用的命令對象,且是池的管理是自增長模式,則生成新的命令并返回給調(diào)用者------else if autoIncreaseStmtCache[statementIndex]is truereturn aConnArray[connectionPointer].prepareStatement(aSQLArray[statementIndex])//-----其他情況,則拋出異常給調(diào)用者------elsethrow error“Statement Not Available”在該線程獲取了命令對象,及對應的連接對象時,該線程就可以使用該連接作為訪問數(shù)據(jù)庫的連接,將該命令對象來向數(shù)據(jù)庫發(fā)送SQL語句命令來訪問數(shù)據(jù)庫,對數(shù)據(jù)庫進行檢索或者操作數(shù)據(jù)庫,來實現(xiàn)上述步驟303的內(nèi)容。根據(jù)某連接對象的命令對象對數(shù)據(jù)庫進行的訪問步驟和現(xiàn)有技術相同,不再贅述。
步驟409為該線程訪問數(shù)據(jù)庫結(jié)束,釋放所調(diào)用的連接(Connection)和命令對象(PreparedStatement對象),以提供給后續(xù)的請求使用的步驟,是上述步驟304的具體實現(xiàn)。如下為釋放命令對象到池中的應用邏輯釋其中,必須傳入的參數(shù)包括命令對象的索引、將要返回到池內(nèi)的PreparedStatement命令對象。
釋放命令接口到PreparedStatement命令池的簡要程序邏輯如下statementQueue[statementIndex].add(aStatement)這里,進一步強調(diào)說明的是PreparedStatement命令并沒有被關閉,只是釋放到StatementQueue緩沖隊列中以供后續(xù)的請求使用。
另外,步驟410是該命令池不再使用時,銷毀該命令池的步驟,如下為銷毀命令池的簡要程序邏輯//-----從命令池中獲取所有的命令隊列,并循環(huán)釋放所占用的資源------for statementIndex from 0 to numberOfSQLs-1//-----循環(huán)從相應的命令隊列上獲取命令------for cacheCount from 0 to aPStmtCountArray[statementIndex]-1//-----從命令隊列中獲取命令并釋放資源------statementQueue[statementIndex].remove().close()end forend for//-----循環(huán)釋放連接池的資源------for connectionIndex from 0 to numOfConnectionsaConnArray[connectionIndex].close()end for通過本發(fā)明所述方法,不同的線程可以使用不同的連接(Connection)所提供的同一命令對象(PreparedStatement對象)訪問數(shù)據(jù)庫,消除了多線程應用程序數(shù)據(jù)庫連接被線程獨占的阻塞,并且在同一個連接上允許被不同的線程執(zhí)行不同的命令,這樣在給定的性能標準上,有效地減少應用與數(shù)據(jù)庫建立的連接數(shù)。
通過不同連接上對命令對象的分布,實現(xiàn)對不同的SQL命令分別在連接上實現(xiàn)了負載均衡控制,滿足了不同SQL命令不同執(zhí)行的頻率的有效性并提升了性能。
另外,簡化了應用邏輯,因為只要關心PreparedStatement對象,不需要了解從數(shù)據(jù)庫連接中如何獲取命令對象和準備(解析SQL語句、編譯SQL語句以及計劃和優(yōu)化數(shù)據(jù)獲取路徑)對象的過程。
以上所述僅為本發(fā)明的較佳實施例而已,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進等,均應包含在本發(fā)明的保護范圍之內(nèi)。
權利要求
1.一種多線程應用程序訪問數(shù)據(jù)庫的方法,預先建立到數(shù)據(jù)庫的不同的連接并進行緩存,其特征在于,分別在所述不同連接里建立要使用的命令對象并緩存入命令池,當某個線程調(diào)用某連接和該連接上的命令對象訪問數(shù)據(jù)庫時,包括以下步驟A、判斷命令池中是否有未被調(diào)用的所述命令對象,若有,則執(zhí)行下一步,否則選擇一個連接并在該連接上建立所述命令對象;B、選擇所述的命令對象和該命令對象所屬的連接;C、所述線程調(diào)用所選擇的連接和命令對象訪問數(shù)據(jù)庫。
2.根據(jù)權利要求1所述的方法,其特征在于,所述分別在不同連接里建立要使用的命令對象的步驟包括從配置文件或者數(shù)據(jù)庫配置項表中讀取命令池的配置信息來構(gòu)建命令池;所述配置信息包括要創(chuàng)建所述命令對象的數(shù)量;獲取連接對象,根據(jù)所述配置信息依次在不同的連接對象上創(chuàng)建所述的命令對象。
3.根據(jù)權利要求2所述的方法,其特征在于,所述配置信息更改時,讀取更新的配置信息更新命令池的配置。
4.根據(jù)權利要求1所述的方法,其特征在于,進一步包括對命令池中的各個命令對象的調(diào)用的頻率進行統(tǒng)計,在特定的周期內(nèi)刪除命令池中被調(diào)用頻率低的命令對象。
5.根據(jù)權利要求1所述的方法,其特征在于,在線程結(jié)束調(diào)用所述連接和命令對象時,進一步包括該線程釋放命令對象和所述的連接的步驟。
6.根據(jù)權利要求1所述的方法,其特征在于,取消使用所述命令池時,進一步包括銷毀所述命令池的步驟。
7.根據(jù)權利要求1所述的方法,其特征在于,所述的命令對象為準備好的命令對象PreparedStatement對象。
全文摘要
本發(fā)明提供了一種多線程應用程序訪問數(shù)據(jù)庫的方法,預先建立不同的連接進行緩存,在不同連接里分別建立要使用的命令對象緩存入命令池,當某個線程訪問數(shù)據(jù)庫時,包括以下步驟A、判斷命令池中是否有未被調(diào)用的所述命令對象,若有,則執(zhí)行步驟B,否則在一連接對象上建立所述命令對象;B、選擇所述命令對象、命令對象所屬的連接對象;C、該線程調(diào)用所選取的連接對象和命令對象訪問數(shù)據(jù)庫;在結(jié)束該調(diào)用時,釋放命令對象回命令池。使用本發(fā)明,解決了多線程程序通過JDBC API訪問數(shù)據(jù)庫阻塞問題,提高數(shù)據(jù)庫的訪問性能。
文檔編號G06F9/46GK1869939SQ20051007302
公開日2006年11月29日 申請日期2005年5月27日 優(yōu)先權日2005年5月27日
發(fā)明者張前鋒, 斯瑞佛尼, 郁建中, 商托斯 申請人:華為技術有限公司