<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    ibatis dbcp連接數(shù)據(jù)庫(kù)問題(上)

     (2007-12-20 22:43:33)
    標(biāo)簽: 

    it/科技

    分類: javaEE
    我是懶人,就不自己寫了,就直接引用我找到的兩篇博文:
    最近網(wǎng)站會(huì)出現(xiàn)一個(gè)現(xiàn)象是,在并發(fā)量大的時(shí)候,Tomcat或JBoss的服務(wù)線程會(huì)線程掛起,同時(shí)服務(wù)器容易出現(xiàn)數(shù)據(jù)連接的 java.net.SocketException: Broken pipe  的錯(cuò)誤。剛才開始咋一看感覺像是DB端處理不來或是DB端的連接時(shí)間到了wait_timeout 的時(shí)間強(qiáng)行斷開。出于這兩個(gè)目的,網(wǎng)收集了一些資料后,有的說法是在DB的 wait_timeout 時(shí)間后斷開的一些連接在連接池中處于空閑狀態(tài),當(dāng)應(yīng)用層獲取該連接后進(jìn)行的DB操作就會(huì)發(fā)生上面這個(gè)錯(cuò)誤。
         但在我查看了DBCP連接池代碼和做了些測(cè)試后,發(fā)生這種說法并非正確。
         1. 首先,出現(xiàn) Broken pipe 的錯(cuò)誤不是因連接超時(shí)所致,這個(gè)錯(cuò)誤只有在Linux下多發(fā),就是在高并發(fā)的情況下,網(wǎng)絡(luò)資源不足的情況出現(xiàn)的, 會(huì)發(fā)送SIGPIPE信號(hào),LINUX下默認(rèn)程序退出的,具體解決辦法目前還未找到合適的,有的說法是在Linux的環(huán)境變量中設(shè)置: _JAVA_SR_SIGNUM = 12 基本就可以解決,但經(jīng)測(cè)試結(jié)果看并未解決。對(duì)于該問題持續(xù)關(guān)注中。
         2. 之后,Broken pipe 問題未徹底解決,那么對(duì)于DBCP連接池只好對(duì)一些作廢的連接要進(jìn)行強(qiáng)制回收,若這里不做強(qiáng)制回收的話,最終也就會(huì)導(dǎo)致 pool exhausted 了,所以這一步一定要加上保護(hù)。配置如下:
    1. #### 是否在自動(dòng)回收超時(shí)連接的時(shí)候打印連接的超時(shí)錯(cuò)誤   
    2. dbcp.logAbandoned=true  
    3. #### 是否自動(dòng)回收超時(shí)連接   
    4. dbcp.removeAbandoned=true  
    5. #### 超時(shí)時(shí)間(以秒數(shù)為單位)   
    6. dbcp.removeAbandonedTimeout=150  

         3. 對(duì)于DB的 wait_timeout 空閑連接時(shí)間設(shè)置,在超過該時(shí)間值的連接,DB端會(huì)強(qiáng)行關(guān)閉,經(jīng)測(cè)試結(jié)果,即使DB強(qiáng)行關(guān)閉了空閑連接,對(duì)于DBCP而言在獲取該連接時(shí)無(wú)法激活該連接,會(huì)自動(dòng)廢棄該連接,重新從池中獲取空閑連接或是重新創(chuàng)建連接,從源代碼上看,這個(gè)自動(dòng)完成的激活邏輯并不需要配置任何參數(shù),是DBCP的默認(rèn)操作。故對(duì)于網(wǎng)上的不少說連接池時(shí)間配置與DB不協(xié)調(diào)會(huì)導(dǎo)致 Broken pipe 的說法是錯(cuò)誤,至少對(duì)于DBCP是不會(huì)出現(xiàn)該問題,也許C3P0是這樣。
          不過對(duì)于連接池的優(yōu)化而言,本來就在池里空閑的連接被DB給強(qiáng)行關(guān)閉也不件好事,這里可以組合以下幾個(gè)配置解決該問題:

    java 代碼
    1. false 空閑時(shí)是否驗(yàn)證, 若不通過斷掉連接, 前提是空閑對(duì)象回收器開啟狀態(tài)   
    2. dbcp.testWhileIdle true  
    3. -1 以毫秒表示空閑對(duì)象回收器由運(yùn)行間隔。值為負(fù)數(shù)時(shí)表示不運(yùn)行空閑對(duì)象回收器   
    4. 若需要回收, 該值最好小于 minEvictableIdleTimeMillis 值   
    5. dbcp.timeBetweenEvictionRunsMillis 300000 
    6. 1000*60*30 被空閑對(duì)象回收器回收前在池中保持空閑狀態(tài)的最小時(shí)間, 毫秒表示   
    7. 若需要回收, 該值最好小于DB中的 wait_timeout   
    8. dbcp.minEvictableIdleTimeMillis 320000  

          4. 最后,還有一個(gè)就是DBCP的maxWait參數(shù),該參數(shù)值不宜配置太大,因?yàn)樵诔叵臐M時(shí),該會(huì)掛起線程等待一段時(shí)間看看是否能獲得連接,一般到池耗盡的可能很少,若真要耗盡了一般也是并發(fā)太大,若此時(shí)再掛線程的話,也就是同時(shí)掛起了Server的線程,若到Server線程也掛滿了,不光是訪問DB的線程無(wú)法訪問,就連訪問普通頁(yè)面也無(wú)法訪問了。結(jié)果是更糕。

            這樣,通過以上幾個(gè)配置,DBCP連接池的連接泄漏應(yīng)該不會(huì)發(fā)生了(當(dāng)然除了程序上的連接泄漏),不過對(duì)于并發(fā)大時(shí)Linux上的BrokenPipe 問題最好能徹底解決。但是對(duì)于并發(fā)量大時(shí),Tomcat或JBoss的服務(wù)線程會(huì)掛起的原因還是未最終定位到原因,目前解決了DBCP的影響后,估計(jì)問題可能會(huì)是出現(xiàn)在 mod_jk 與 Tomcat 的連接上了,最終原因也有可能是 broken pipe 所致。關(guān)注與解決中……

     

    2.ibatis使用dbcp連接數(shù)據(jù)庫(kù)

    一、建立數(shù)據(jù)表(我用的是oracle 9.2.0.1)

    prompt PL/SQL Developer import file
    prompt Created on 2007年5月24日 by Administrator
    set feedback off
    set define off
    prompt Dropping T_ACCOUNT...
    dro p table T_ACCOUNT cascade constraints; (注意:這里由于ISP限制上傳drop,所以加了一個(gè)空格)
    prompt Creating T_ACCOUNT...
    create table T_ACCOUNT
    (
      ID           NUMBER not null,
      FIRSTNAME    VARCHAR2(2),
      LASTNAME     VARCHAR2(4),
      EMAILADDRESS VARCHAR2(60)
    )
    ;
    alter table T_ACCOUNT
      add constraint PK_T_ACCOUNT primary key (ID);

    prompt Disabling triggers for T_ACCOUNT...
    alter table T_ACCOUNT disable all triggers;
    prompt Loading T_ACCOUNT...
    insert into T_ACCOUNT (ID, FIRSTNAME, LASTNAME, EMAILADDRESS)
    values (1, '王', '三旗', 'E_wsq@msn.com');
    insert into T_ACCOUNT (ID, FIRSTNAME, LASTNAME, EMAILADDRESS)
    values (2, '冷', '宮主', 'E_wsq@msn.com');
    commit;
    prompt 2 records loaded
    prompt Enabling triggers for T_ACCOUNT...
    alter table T_ACCOUNT enable all triggers;
    set feedback on
    set define on
    prompt Done.


    二、在工程中加入

    commons-dbcp-1.2.2.jar

    commons-pool-1.3.jar

    ibatis-common-2.jar

    ibatis-dao-2.jar

    ibatis-sqlmap-2.jar

    三、編寫如下屬性文件

    jdbc.properties

    #連接設(shè)置
    driverClassName=oracle.jdbc.driver.OracleDriver
    url=jdbc:oracle:thin:@90.0.12.112:1521:ORCL
    username=gzfee
    password=1

    #<!-- 初始化連接 -->
    initialSize=10

    #<!-- 最大空閑連接 -->
    maxIdle=20

    #<!-- 最小空閑連接 -->
    minIdle=5

    #最大連接數(shù)量
    maxActive=50

    #是否在自動(dòng)回收超時(shí)連接的時(shí)候打印連接的超時(shí)錯(cuò)誤
    logAbandoned=true

    #是否自動(dòng)回收超時(shí)連接
    removeAbandoned=true

    #超時(shí)時(shí)間(以秒數(shù)為單位)
    removeAbandonedTimeout=180

    #<!-- 超時(shí)等待時(shí)間以毫秒為單位 6000毫秒/1000等于60秒 -->
    maxWait=1000


    四、將上面建立的屬性文件放入classes下

    注:如果是用main類測(cè)試則應(yīng)在工程目錄的classes下,如果是站點(diǎn)測(cè)試則在web-inf的classes目錄下

    五、寫ibatis與DBCP的關(guān)系文件

    DBCPSqlMapConfig.xml

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE sqlMapConfig     
        PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
        "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

    <sqlMapConfig>
        <properties resource ="jdbc.properties"/>
        <transactionManager  type ="JDBC">
          <dataSource  type ="DBCP">
               <property  name ="JDBC.Driver"  value ="${driverClassName}"/>
               <property  name ="JDBC.ConnectionURL"  value ="${url}" />
               <property  name ="JDBC.Username"  value ="${username}" />
               <property  name ="JDBC.Password"  value ="${password}" />
               <property  name ="Pool.MaximumWait"  value ="30000" />
               <property  name ="Pool.ValidationQuery"  value ="select sysdate from dual" />
               <property  name ="Pool.LogAbandoned"  value ="true" />
               <property  name ="Pool.RemoveAbandonedTimeout"  value ="1800000" />
               <property  name ="Pool.RemoveAbandoned"  value ="true" />
          </dataSource>
        </transactionManager>
        <sqlMap resource="com/mydomain/data/Account.xml"/> (注:這里對(duì)應(yīng)表映射)
    </sqlMapConfig>

    六、寫數(shù)據(jù)表映射文件

    Account.xml

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE sqlMap     
        PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     
        "http://ibatis.apache.org/dtd/sql-map-2.dtd">

    <sqlMap namespace="Account">

      <!-- Use type aliases to avoid typing the full classname every time. -->
      <typeAlias alias="Account" type="com.mydomain.domain.Account"/>

      <!-- Result maps describe the mapping between the columns returned
           from a query, and the class properties.  A result map isn't
           necessary if the columns (or aliases) match to the properties
           exactly. -->
      <resultMap id="AccountResult" class="Account">
        <result property="id" column="id"/>
        <result property="firstName" column="firstName"/>
        <result property="lastName" column="lastName"/>
        <result property="emailAddress" column="emailAddress"/>
      </resultMap>

      <!-- Select with no parameters using the result map for Account class. -->
      <select id="selectAllAccounts" resultMap="AccountResult">
        select * from T_ACCOUNT
      </select>

      <!-- A simpler select example without the result map.  Note the
           aliases to match the properties of the target result class. -->
      <select id="selectAccountById" parameterClass="int" resultClass="Account">
        select
          id as id,
          firstName as firstName,
          lastName as lastName,
          emailAddress as emailAddress
        from T_ACCOUNT
        where id = #id#
      </select>
      
      <!-- Insert example, using the Account parameter class -->
      <insert id="insertAccount" parameterClass="Account">
        insert into T_ACCOUNT (
          id,
          firstName,
          lastName,
          emailAddress
        values (
          #id#, #firstName#, #lastName#, #emailAddress#
        )
      </insert>

      <!-- Update example, using the Account parameter class -->
      <update id="updateAccount" parameterClass="Account">
        update T_ACCOUNT set
          firstName = #firstName#,
          lastName = #lastName#,
          emailAddress = #emailAddress#
        where
          id = #id#
      </update>

      <!-- Delete example, using an integer as the parameter class -->
      <delete id="deleteAccountById" parameterClass="int">
        delet e from T_ACCOUNT where id = #id# (注意:這里由于ISP限制上傳delete,所以加了一個(gè)空格)
      </delete>

    </sqlMap>

     

    posted on 2011-04-22 13:45 ivaneeo 閱讀(1062) 評(píng)論(0)  編輯  收藏 所屬分類: java魔力
    主站蜘蛛池模板: 免费A级毛片无码免费视| 毛片免费观看视频| 无码人妻AV免费一区二区三区| 久久免费看黄a级毛片| 日本不卡在线观看免费v| 亚洲国产精品无码成人片久久| 亚洲视频在线观看视频| 看亚洲a级一级毛片| 麻豆成人久久精品二区三区免费| 成人免费网站在线观看| 亚洲一级毛片在线观| 在线看片免费人成视频福利| 国产免费无遮挡精品视频| 亚洲神级电影国语版| 中文字幕无线码中文字幕免费| 99精品国产免费久久久久久下载| 国产日韩成人亚洲丁香婷婷| 最新亚洲精品国偷自产在线| 国产午夜精品久久久久免费视| 可以免费观看的一级毛片| youjizz亚洲| 国产精品公开免费视频| 亚洲欧美综合精品成人导航| **毛片免费观看久久精品| 亚洲日韩国产精品无码av| 玖玖在线免费视频| 亚洲日韩中文字幕| 在线观看免费毛片| 亚洲一区在线观看视频| 日韩成人在线免费视频| 四虎影视久久久免费| 一本久久综合亚洲鲁鲁五月天| 国产AV旡码专区亚洲AV苍井空| 日韩午夜免费视频| 在线观看黄片免费入口不卡| 国产亚洲精品精品国产亚洲综合| 永久免费av无码入口国语片| 亚洲综合偷自成人网第页色| 在线观看免费高清视频| gogo免费在线观看| 国产精品亚洲αv天堂无码|