鏈接池如何作保活性檢測

前段時間有網友發來信息問:您的鏈接池怎麼沒有保活性檢測呢?  其實小蜜蜂鏈接池不但有,並且還技高一籌呢,並且咱們的檢測方式是獲取到鏈接後的第一時間進行存活性檢測的,若是檢測無效,則會主動從池中移除該鏈接,並嘗試獲取下一個鏈接,再檢測,一直取到有效的鏈接或超時退出;第一時間的檢測在必定程度保證了池的性能方面的優點【好比國際大牌某池的作法: 從隊列獲到一個鏈接後,退出borrow方法,檢測結果發現鏈接無效,則會再次進入borrow方法,我相信有必定的功底朋友能對比看出孰優孰劣(我但願個人代碼不只僅體現出卓越的性能,更重的要體現出嚴謹性,優雅性)】小蜜蜂池的思想很精煉,代碼方式不搞彎彎繞繞:除非我超時,不然我必須拿到有效的鏈接。話題有點扯遠了,繼續回到咱們的中心話題。java

一:鏈接存活性檢測方式git

熟悉鏈接池的朋友,都知道鏈接池通常都有鏈接存活性檢測手段,常見的方式有github

A: Connection.IsValid方法(JDK1.6之後)sql

B: 利用Statement執行一段SQL語句(Java1.5以前)性能

通常性鏈接池都支持上述兩種方式,若驅動不支持第一種方式時,鏈接池會按第二種方式:間隔一段時間的方式執行某段SQL語句,若無異常則斷定爲有效鏈接,因此給鏈接池提供測試性腳本是很是有必要的(保底性方式),測試代碼的大致以下:測試

public boolean isAlive(Connection con,String sql){
   Statement st=null;
   try{
       st =con.createStatement();
       st.execute(sql);
       return true;
    }catch(Exception e){
      return false;
    }finally{
      if(st!=null)try{st.close();}catch(Exception e){}
    }
}

二:SQL與事務回滾url

看過上述代碼的朋友,也許會有下面疑問.net

A:這個SQL使用什麼樣的語句好呢?code

回答:一般是一條簡單性的查詢語句,有的池默認語句:SELECT 1 或 SELECT 1 FROM DUALblog

B:這條語句能是一條insert語句或update語句嗎?

 回答:固然能夠,有的池沒有限定這條語句到底寫成啥樣。

C: 若是是一條insert語句,鏈接池長時間運行後,確定會反覆執行這條SQL,那麼某表不會膨脹很大?

 回答:是的,若是不加上某些控制,長時間運做某表是有可能形成膨脹現象,這是一個很好的問題。

針對問題C, 我我的的觀點是加入事務控制,避免來 ‘真’的(實際性改變),那麼上述代碼就須要調整爲:

public boolean isAlive(Connection con,String sql){
   Statement st=null;
   boolean changed=false;

   try{
       if(con.getAutoCommit()){
          con.setAutoCommit(false);
          changed=true;
       }

       st =con.createStatement();
       st.execute(sql);
       return true;
    }catch(Exception e){
      return false;
    }finally{
      con.rollback();//回滾操做,必須放在finally中
      if(st!=null)try{st.close();}catch(Exception e){}
      if(changed) con.setAutoCommit(true);
    }
}

看了上述代碼的朋友也許會提出: rollback爲啥要寫在finally中呢,直接跟在 execute方法後面很差嗎?

個人回答:失敗未必沒有寫入數據,finally是最佳位置處,咱們來設想假如用戶配置以下一條SQL:

select xxx() from dual

熟悉Oracle的朋友對這樣的寫法不陌生吧,利用一條SQL語句去執行一個存儲過程,在這個基礎上,咱們把問題繼續往前推動一步:假如這個過程當中執行了100條insert語句,當執行完99條以後,最後一條insert失敗了又或者所有成功呢.  親愛的朋友們請告訴我,這種狀況下是否須要回滾呢? 答案是確定的,除非你想往庫里加點料。

三: 事務切換性問題(追加點料

setAutoCommit朋友都知道這個是用於事務方面的方法,可是您知道:這個方法不能隨便切換嗎?隨意切換會有什麼後果?個人代碼(https://github.com/Chris2018998/BeeCP/blob/master/src/main/java/cn/beecp/pool/ProxyConnectionBase.java)的83行代碼:在 setAutoCommit方法中有一個髒標記檢查異常,也許您會很好奇,爲啥這樣作呢? 個人回答是:數據保護的嚴謹性,在這種狀況下,要麼回滾,要麼提交,不然不容許改變。下面咱們作一個測試,請看下面步驟圖(Oracle11g)

第一步:查看數據某表記錄(空表)

第二步:編寫測試代碼(AutoComit 從false切換到true, 中間不回滾)

第三步:查看錶結果(切換後的結果,被保存進庫了)

(這個測試主要提醒你們,鏈接上的贓操做,不當心的話,後續的commit或關閉時,會保存存進庫裏)

相關文章
相關標籤/搜索