Oracle之數據庫連接池


連接池出現的背景:

數據庫連接是一種關鍵的、有限的、昂貴的資源,這一點在多用戶的網頁應用程序中體現得尤為突出。對數據庫連接的管理能顯著影響到整個應用程序的伸縮性和健壯性,影響到程序的性能指標。數據庫連接池正是針對這個問題提出來的。

數據量少的情況:

每一次web請求都要建立一次數據庫連接。建立連接是一個費時的活動,每次都得花費0.05s~1s的時間,而且系統還要分配內存資源。這個時間對於一次或幾次數據庫操作,或許感覺不出系統有多大的開銷。如下面的用戶查詢案例,如果同時有1000人訪問,就會不斷的有數據庫連接、斷開操作:

 

 

 “數據庫連接”是一種稀缺的資源,為了保障網站的正常使用,應該對其進行妥善管理。其實我們查詢完數據庫后,如果不關閉連接,而是暫時存放起來,當別人使用時,把這個連接給他們使用。就避免了一次建立數據庫連接和斷開的操作時間消耗。原理如下:

我們自己嘗試開發一個連接池,來為上面的查詢業務提供數據庫連接服務:

       ①   編寫class 實現DataSource 接口

       ②   在class構造器一次性創建10個連接,將連接保存LinkedList中

       ③   實現getConnection  從 LinkedList中返回一個連接

       ④   提供將連接放回連接池中方法

1、連接池代碼        

      public class MySelfDataSource implements DataSource {  
//鏈表 --- 實現棧結構,鏈表結構方便插入跟刪除操作 private LinkedList<Connection> dataSources = new LinkedList<Connection>(); //初始化連接數量 public MySelfDataSource() { //一次性創建10個連接 for(int i = 0; i < 10; i++) { try { //1、裝載Oracle驅動對象,作用是:
1、裝載。將字節碼讀入內存,並產生一個與之對應的java.lang.Class類對象
2、連接。這一步會驗證字節碼,為static變量分配內存,並賦默認值(0或null),並可選的解析符號引用(這里不理解沒關系)
3、初始化。為類的static變量賦初始值,假如有static int a = 1;這個將a賦值為1的操作就是這個時候做的。除此之外,還要調用類的static塊。(這一步是要點) Class.forName("oracle.jdbc.OracleDriver"
);// 或者使用DriverManager.registerDriver(new OracleDriver());
                               //2、通過JDBC建立數據庫連接
                               Connection con =DriverManager.getConnection(
                                  "jdbc:oracle:thin:@10.148.3.20:1521:tgtest", "saa", "123");
                               //3、將連接加入連接池中
                               dataSources.add(con);
                            } catch (Exception e) {
                               e.printStackTrace();
                            }
                     }
              }
 
              @Override
              publicConnection getConnection() throws SQLException {
                     //取出連接池中一個連接
                     finalConnection conn = dataSources.removeFirst(); // 刪除第一個連接返回
                     return conn;
              }
 
              //將連接放回連接池
              publicvoid releaseConnection(Connection conn) {
                     dataSources.add(conn);
                     }
       }

  2.使用連接池重構我們的用戶查詢函數  

    //查詢所有用戶
       Public void FindAllUsers(){
              //1、使用連接池建立數據庫連接
              MyDataSource dataSource = new MyDataSource();
              Connection conn =dataSource.getConnection();        
              //2、創建狀態
              Statement state =con.createStatement();           
              //3、查詢數據庫並返回結果
              ResultSet result =state.executeQuery("select * from users");           
              //4、輸出查詢結果
              while(result.next()){
                     System.out.println(result.getString("email"));
              }            
              //5、斷開數據庫連接
              result.close();
              state.close();
              //6、歸還數據庫連接給連接池
              dataSource.releaseConnection(conn);
        }

  

影響因素:

數據庫連接池在初始化時將創建一定數量的數據庫連接放到連接池中,這些數據庫連接的數量是由最小數據庫連接數制約。無論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量。連接池的最大數據庫連接數量限定了這個連接池能占有的最大連接數,當應用程序向連接池請求的連接數超過最大連接數量時,這些請求將被加入到等待隊列中。數據庫連接池的最小連接數和最大連接數的設置要考慮到下列幾個因素:

1. 最小連接數
是連接池一直保持的數據庫連接,所以如果應用程序對數據庫連接的使用量不大,將會有大量的數據庫連接資源被浪費。
2. 最大連接數
是連接池能申請的最大連接數,如果數據庫連接請求超過此數,后面的數據庫連接請求將被加入到等待隊列中,這會影響之后的數據庫操作。
3. 最小連接數與最大連接數差距
最小連接數與最大連接數相差太大,那么最先的連接請求將會獲利,之后超過最小連接數量的連接請求等價於建立一個新的數據庫連接。不過,這些大於最小連接數的數據庫連接在使用完不會馬上被釋放,它將被放到連接池中等待重復使用或是空閑超時后被釋放。

原理:

連接池基本的思想是在系統初始化的時候,將數據庫連接作為對象存儲在內存中,當用戶需要訪問數據庫時,並非建立一個新的連接,而是從連接池中取出一個已建立的空閑連接對象。使用完畢后,用戶也並非將連接關閉,而是將連接放回連接池中,以供下一個請求訪問使用。而連接的建立、斷開都由連接池自身來管理。同時,還可以通過設置連接池的參數來控制連接池中的初始連接數、連接的上下限數以及每個連接的最大使用次數、最大空閑時間等等。也可以通過其自身的管理機制來監視數據庫連接的數量、使用情況等。

作用:它大大提供了數據庫連接的利用率,減小了內存吞吐的開銷。

Java連接池:

在Java中開源的數據庫連接池有以下幾種 :
1、C3P0:是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate 一起發布,包括了實現jdbc3和jdbc2擴展規范說明的Connection 和Statement 池的DataSources 對象。
2、Proxool:是一個Java SQL Driver驅動程序,提供了對選擇的其它類型的驅動程序的連接池封裝。可以非常簡單的移植到現存的代碼中,完全可配置,快速、成熟、健壯。可以透明地為現存的JDBC驅動程序增加連接池功能。
3、Jakarta DBCP:DBCP是一個依賴Jakartacommons-pool 對象池機制的數據庫連接池。DBCP可以直接的在應用程序中使用。
4、DDConnectionBroker:是一個簡單、輕量級的數據庫連接池。
5、DBPool:是一個高效、易配置的數據庫連接池。它除了支持連接池應有的功能之外,還包括了一個對象池,使用戶能夠開發一個滿足自己需求的數據庫連接池。
6、XAPool:是一個XA數據庫連接池。它實現了javax.sql.XADataSource並提供了連接池工具。
7、Primrose:是一個Java開發的數據庫連接池。當前支持的容器包括Tomcat4&5、Resin3與JBoss3。它同樣也有一個獨立的版本,可以在應用程序中使用而不必運行在容器中。Primrose通過一個WEB接口來控制SQL處理的追蹤、配置,以及動態池管理。在重負荷的情況下可進行連接 請求隊列處理。
8、SmartPool:是一個連接池組件,它模仿 應用服務器 對象池的特性。SmartPool能夠解決一些臨界問題如連接泄漏(connection leaks)、連接阻塞、打開的JDBC對象(如Statements、PreparedStatements)等。SmartPool的特性包括:
  • 支持多個pool
  • 自動關閉相關聯的JDBC對象
  • 在所設定time-outs之后察覺連接泄漏
  • 追蹤連接使用情況
  • 強制啟用最近最少用到的連接
  • 把SmartPool“包裝”成現存的一個pool
9、MiniConnectionPoolManager:是一個輕量級 JDBC數據庫連接池。它只需要Java1.5(或更高)並且沒有依賴第三方包。
10、BoneCP:是一個快速、開源的數據庫連接池。幫用戶管理 數據連接,讓應用程序能更快速地訪問數據庫。比C3P0/DBCP連接池速度快25倍。
11、 Druid:Druid不僅是一個數據庫連接池,還包含一個ProxyDriver、一系列內置的JDBC組件庫、一個SQL Parser。
支持所有JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
Druid針對Oracle和MySql做了特別優化,比如:
  • Oracle的PS Cache內存占用優化
  • MySql的ping檢測優化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,這是一個手寫的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象語法樹很方便。
簡單SQL語句用時10微秒以內,復雜SQL用時30微秒。
通過Druid提供的SQL Parser可以在JDBC層攔截SQL做相應處理,比如說分庫分表、審計等。Druid防御SQL注入攻擊的WallFilter,就是通過Druid的SQL Parser分析語義實現的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM