[英]Creating a database connection pool
需要有關創建數據庫連接池的信息(無論數據庫如何),以及它們的效率如何? 他們可以提高績效的條件是什么。
如何明確創建它?
你的問題有點模棱兩可:
你想在家里建立一個連接池實現嗎? 如果是這樣,這是一個很好的起點: http : //java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.html 但是對於生產環境而言,這是非常不鼓勵的。 更好地使用現有且經過全面測試的連接池API,如DBCP或C3P0 。
或者您想知道如何使用連接池? 如果是這樣,答案取決於您正在使用的連接池API。 幸運的是,通常可以在相關API的網站上找到它。
或者您想知道何時/為何使用連接池? 如果是這樣,如果您擁有一個長期存在的應用程序(例如Web應用程序)並且您需要經常連接數據庫,它肯定會增強連接性能。 正常的JDBC實踐是:在盡可能短的范圍內(即在同一個方法塊內)獲取並關閉Connection
, Statement
和ResultSet
。 由於連接相當昂貴,可能需要200毫秒甚至更長時間,因此使用連接池要快得多。 它按需提供連接,並負責實際關閉連接。 但這並不意味着您可能會改變編寫JDBC的方式,您仍然需要在盡可能最大的范圍內獲取並關閉它們。 您需要更改的唯一方法是獲取連接的方式。 例如改變
connection = driverManager.getConnection();
至
connection = connectionPool.getConnection();
只要您的JDBC代碼編寫得很好,就不需要進行任何更改。
Apache DBCP的介紹頁很好地總結了它:
為每個用戶創建新連接可能非常耗時(通常需要多秒的時鍾時間),以便執行可能需要幾毫秒的數據庫事務。 在公共托管的Internet應用程序中,每個用戶打開一個連接可能是不可行的,因為同時用戶的數量可能非常大。 因此,開發人員通常希望在所有應用程序的當前用戶之間共享打開連接的“池”。 在任何給定時間實際執行請求的用戶數通常占活動用戶總數的很小百分比,並且在請求處理期間是唯一需要數據庫連接的時間。 應用程序本身登錄到DBMS,並在內部處理任何用戶帳戶問題。
效率如何? 取決於實施。 通常我希望池在啟動時或根據請求實例化連接。 第一個連接將需要與數據庫的真實連接,此后當您請求連接時,您將獲得一個現有的池連接。 因此,第一個連接請求將占用大部分時間,之后您只是從集合中提取對象(非常快)。
創建與數據庫的連接是非常昂貴的操作。 連接池是創建和緩存的數據庫連接的實例。 無論何時需要與數據庫建立新連接,都會使用池中的一個連接,而不是創建新連接。 某些平台(如.NET + SQL Server)默認使用連接池(您無需創建自己的連接池)。 因此,它們通過每次創建新連接節省時間,基本上提高了性能。
使用連接池可以節省每次訪問的時間,因為已建立連接。
此外,至少在Oracle上,您保持編譯語句鏈接到連接,因此重復執行相同的SQL語句甚至更快。
(如果您使用的是Java / JDBC,請參閱PreparedStatement)
反性能的唯一風險是當你在池中保留太多空閑連接時,相關的資源(你的一方和數據庫)都被浪費了。
有些數字,請在基准測試部分查看BoneCP( http://jolbox.com )。 請記住,preparedStatements等與連接相關聯,因此如果您自己處理連接,則需要一次又一次地准備它們(連接池也會為您緩存這些連接)。
到目前為止我最好的解決方案:使用一個lazyDataSource,它只在你真正需要它時給你一個連接(即不是盲目的 - 如果數據可以來自緩存,那么你可以避免數據庫命中)
使用tomcat創建數據庫連接池
1. Tomcat在里面輸入資源:conf / context.xml
將資源條目放在context.xml文件中:
<!-- jdbc/jndiName jndi -->
<Resource name="jdbc/jndiName" auth="Container" type="javax.sql.DataSource" initialSize="1" maxActive="100" maxIdle="30" maxWait="10000" username="enter username" password="enter password" driverClassName="diver name" url="jdbc database url"/>
2.創建一個將創建連接池的類
public class MyConnectionFactory {
private static String module = "[ QuoteConnectionFactory ]";
private static QuoteConnectionFactory connectionFactory;
protected QuoteConnectionFactory() {
}
/**
*
* @return=>getInstance() is a static method which will return the instance
* of its own class
*/
public static QuoteConnectionFactory getInstance() {
if (connectionFactory == null)
connectionFactory = new QuoteConnectionFactory();
return connectionFactory;
}
/**
*
* @param jndiName
*/
public Connection getConnection(String jndiName) {
System.out.println("jndiName=======" + jndiName);
Connection conn = null;
InitialContext cxt = null;
DataSource dataSource = null;
try {
cxt = new InitialContext();
Context envContext = (Context)cxt.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup(jndiName);
} catch (NamingException e) {
} catch (Exception e) {
}
if (dataSource == null) {
try {
conn = dataSource.getConnection();
} catch (Exception e) {
}
System.out.println("connection===================" + conn);
return conn;
}
}
3.編輯web.xml文件
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/jndiName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
4.在代碼中使用
Connection con= QuoteConnectionFactory.getInstance(). getConnection("jndiName");
創建數據庫連接可能是也可能不是昂貴的操作,具體取決於您的環境以及您打算如何處理它。
如果您要運行一個非常簡單的查詢,那么連接可能需要與查詢一樣長(或更長)。
有些數據庫的連接開銷比其他數據庫大得多; 如果調整正確,mysql應該很少(超過時間進行tcp連接並進行協議握手)。 但是,如果服務器的延遲非常高,即使這樣也非常重要(特別是如果您打算只進行一些查詢)。
如果你打算做100個查詢,或者幾個非常慢的查詢,那么連接時間就會消失得無足輕重。
通常我會說每次都打開一個新的連接,直到你可以證明這是一個真正的性能問題。 使用連接池可能導致BUGS,我們不喜歡:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.