请教ibatis的DBCP连接池和tomcat6的优化问题

时间:2022-09-19 22:56:44
    今年过来接手某城市的交通卡对外查询系统的开发,功能简单,只需输入卡号,取得余额信息即可。采用的是ibatis2+tomcat6+oracle10,代码简单。 
    这个系统的访问量大(具体多少,我也不知道),某一段时间的访问量时多时少等不确定因素。 

    开始的时候,用的是ibatis2的SIMPLE连接池,经常出现的问题是,tomcat启动后,访问一段时间,出现JSP页面无法访问,甚至连静态页面都无法打开,重启tomcat后就可以正常查询,过一段时间又发生那样的问题,后来就优化了tomcat,内容如下: 
    <Connector port="8088" protocol="HTTP/1.1" 
       maxThreads="500"   
       minSpareThreads="50"   
       maxSpareThreads="150"   
       acceptCount="100"         
       connectionTimeout="20000" 
    redirectPort="8443" /> 

    这样也无济于事,后来参考把SIMPLE连接池改成DBCP连接池,同时tomcat的优化保留,ibatis的DBCP连接配置如下: 
     <settings 
        cacheModelsEnabled="true" 
        enhancementEnabled="true" 
        lazyLoadingEnabled="true" 
        errorTracingEnabled="true" 
        maxRequests="400" 
        maxSessions="350" 
        maxTransactions="1" 
        useStatementNamespaces="false" /> 

        <transactionManager type="JDBC"> 
            <dataSource type="DBCP"> 
            <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver" /> 
            <property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@IP:端口:XXX" /> 
            <property name="JDBC.Username" value="XXX" /> 
            <property name="JDBC.Password" value="XXX" /> 

            <property name="Pool.MaximumActiveConnections" value="400" /> 
            <property name="Pool.MaximumIdleConnections" value="200" /> 
            <property name="Pool.MaximumWait" value="10000" /> 
       <!-- <property name="Pool.ValidationQuery" value="select * from ACCOUNT"/>  --> 

            <property name="Pool.LogAbandoned" value="false"/> 
            <property name="Pool.RemoveAbandoned" value="true"/> 
            <property name="Pool.RemoveAbandonedTimeout" value="90"/> 
            </dataSource> 
        </transactionManager> 

    这样的配置之后,有点效果,tomcat启动后,一段时间(不到一天),总是出现无法查询,但是和之前不同的是,JSP页面什么时候都可以打开的,并且速度很快,只是查不出数据,重启tomcat后就好了,过一段时间有发生这样的事情,报错的方法如下: 
    public List getBiact(String cardno) { 
        // 首先初始化iBatis获得一个SqlMapClient对象 
         SqlMapClient sqlMap = null; 
        List biactList = null; 
        try { 
            sqlMap = DB.GetSqlMap(); 
   // sqlMap系统初始化完毕,开始执行getAllUser操作 

    biactList = sqlMap.queryForList("getBiact", cardno); 
    sqlMap.endTransaction(); 

    if (biactList.size() == 0) { 
        sqlMap.queryForList("biact_ex", ""); 
    } else { 
sqlMap.queryForList("success", ""); 
     } 
} catch (Exception e) { 
    System.out.println(e.getMessage()); 
    back = "系统繁忙,请您稍候重试!"; 
    try { 
sqlMap.queryForList("biact_ex", ""); 
    } catch (SQLException e1) { 
e1.printStackTrace(); 
    } 

    
    报出的错误是: 系统繁忙,请您稍候重试! 

    查询语句是简单的两表联合查询,都有索引(不过每天清晨都定时的从另一个数据库把数据导入我要查询的那个表中,数据量大概会有500W条左右,这个是后台程序执行,在导入过程中,会把当前查询的主表的索引删掉,导完后再重建,正常情况下,大概两到三个小时就会把数据导完,错误的发生都在数据导完且索引重建好之后)。 
    由于小弟工作经验不足,之前也没接触这种高访问量的系统,我没法可师了,总是出现这样的问题,我很有压力,请各位同行指教一下,谢谢! 

4 个解决方案

#1


补充:tomcat的catalina.out报这样的错误




--- The error occurred in com/huateng/ibatis/maps/Biactcardacctb.xml.  
--- The error occurred while executing query.  
--- Check the         select        crdpaccno,       crdcity,       crdrealbal,       crdlstdate,       crdlsttime 
    from BiActCardAccTb      where crdfaceid = ? and crdcity=755        .  
--- Check the SQL Statement (preparation failed).  
--- Cause: java.sql.SQLException: Closed Connection
======mmm==8888====
com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in com/huateng/ibatis/maps/Biact_ex.xml.  
--- The error occurred while executing query.  
--- Check the         select biact_ex.Nextval from dual         .  
--- Check the SQL Statement (preparation failed).  
--- Cause: java.sql.SQLException: Closed Connection
Caused by: java.sql.SQLException: Closed Connection
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.ja
va:185)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:12
3)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584)
        at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101)
        at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78)
        at com.huateng.dao.DaoBiactcardacctb.getBiact(DaoBiactcardacctb.java:46)
        at com.huateng.dao.DaoBiactcardacctb.getBiactStr(DaoBiactcardacctb.java:60)
        at com.huateng.common.SetNetService.getCardMsg(SetNetService.java:98)
        at com.huateng.struts.action.QryCardAction.execute(QryCardAction.java:84)
        at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
        at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
        at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
        at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
        at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.SQLException: Closed Connection
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:207)
        at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:839)
        at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:758)
        at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:187)
        at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:167)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.ja
va:173)
        ... 32 more

#2


    问题可能找到了,哎,真悲剧,碰到客户新来的领导,新官上任三把火啊,今天正好让他碰到有人投诉,没事过来找我询问,还说明天找我谈话,好像还要为这个问题zh准备开个会议,真搞笑!
    我也是刚接手这个系统,之前只是部分开发一些模块,这系统不大,不过我发现里面竟然用到分布式,晕倒!
    我发现之前取得ibatis的SqlMapClient的代码是放在static里,然后需要查询语句的,就直接饮用这方法,所以我想,不同的用户查询中,都是用同一个SqlMapClient,而SqlMapClient取得的连接在空闲时间查过设置的等待时间后,会自动关闭,所以再怎么查询都会报:Cause: java.sql.SQLException: Closed Connection的问题,我是这样的分析,然后我去掉static,然后那个方法需要连接数据库,就new它,代码如下:

public class DB {
  private static SqlMapClient sqlMapClient;   
   
   //指定 ibatis配置文件的路径    
   private static String path = "/OracleMapConfig.xml";

   static {   
   java.io.Reader reader = null;   
       try {   
           //初始,加载配置文件   
            reader = com.ibatis.common.resources.Resources.getResourceAsReader(path);   
           sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);   
           sqlMapClient.getCurrentConnection();
           reader.close();
       } catch (Exception ex) {   
           ex.printStackTrace();   
       }   
   }   
 
   public static SqlMapClient GetSqlMap() {   
       return sqlMapClient;   
   }   
}

然后改成:
public class DB {
  private  SqlMapClient sqlMapClient;   
   
   //指定 ibatis配置文件的路径    
   private  String path = "/OracleMapConfig.xml";
   java.io.Reader reader = null;
   
   public SqlMapClient GetSqlMap() {  
       try {   
           //初始,加载配置文件   
        System.out.println("path ==== " + path);
           reader = com.ibatis.common.resources.Resources.getResourceAsReader(path);   
           sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);   
           sqlMapClient.getCurrentConnection();
           reader.close();
       } catch (Exception ex) { 
        System.out.println("加载配置文件失败!");
           ex.printStackTrace();   
       }  
       return sqlMapClient;   
   }   
}


需要用的就new DB,不知道对不对,测试环境也没这个条件,如果还不解决的话,明天就要开会被当活靶子射了,哎,命苦!各位帮帮啊,小弟不胜感激。

#3


因为配置了空闲连接的超时时间。。。所以导致了你上面的情况。。。可以肯定的是,你的问题就是因为这个。。。。上次好像也遇到一个朋友,遇到这种问题。。。

#4


配置空闲连接超时时间?这个会有问题吗

#1


补充:tomcat的catalina.out报这样的错误




--- The error occurred in com/huateng/ibatis/maps/Biactcardacctb.xml.  
--- The error occurred while executing query.  
--- Check the         select        crdpaccno,       crdcity,       crdrealbal,       crdlstdate,       crdlsttime 
    from BiActCardAccTb      where crdfaceid = ? and crdcity=755        .  
--- Check the SQL Statement (preparation failed).  
--- Cause: java.sql.SQLException: Closed Connection
======mmm==8888====
com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in com/huateng/ibatis/maps/Biact_ex.xml.  
--- The error occurred while executing query.  
--- Check the         select biact_ex.Nextval from dual         .  
--- Check the SQL Statement (preparation failed).  
--- Cause: java.sql.SQLException: Closed Connection
Caused by: java.sql.SQLException: Closed Connection
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.ja
va:185)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:12
3)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584)
        at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101)
        at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78)
        at com.huateng.dao.DaoBiactcardacctb.getBiact(DaoBiactcardacctb.java:46)
        at com.huateng.dao.DaoBiactcardacctb.getBiactStr(DaoBiactcardacctb.java:60)
        at com.huateng.common.SetNetService.getCardMsg(SetNetService.java:98)
        at com.huateng.struts.action.QryCardAction.execute(QryCardAction.java:84)
        at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
        at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
        at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
        at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
        at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.SQLException: Closed Connection
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:207)
        at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:839)
        at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:758)
        at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:187)
        at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:167)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.ja
va:173)
        ... 32 more

#2


    问题可能找到了,哎,真悲剧,碰到客户新来的领导,新官上任三把火啊,今天正好让他碰到有人投诉,没事过来找我询问,还说明天找我谈话,好像还要为这个问题zh准备开个会议,真搞笑!
    我也是刚接手这个系统,之前只是部分开发一些模块,这系统不大,不过我发现里面竟然用到分布式,晕倒!
    我发现之前取得ibatis的SqlMapClient的代码是放在static里,然后需要查询语句的,就直接饮用这方法,所以我想,不同的用户查询中,都是用同一个SqlMapClient,而SqlMapClient取得的连接在空闲时间查过设置的等待时间后,会自动关闭,所以再怎么查询都会报:Cause: java.sql.SQLException: Closed Connection的问题,我是这样的分析,然后我去掉static,然后那个方法需要连接数据库,就new它,代码如下:

public class DB {
  private static SqlMapClient sqlMapClient;   
   
   //指定 ibatis配置文件的路径    
   private static String path = "/OracleMapConfig.xml";

   static {   
   java.io.Reader reader = null;   
       try {   
           //初始,加载配置文件   
            reader = com.ibatis.common.resources.Resources.getResourceAsReader(path);   
           sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);   
           sqlMapClient.getCurrentConnection();
           reader.close();
       } catch (Exception ex) {   
           ex.printStackTrace();   
       }   
   }   
 
   public static SqlMapClient GetSqlMap() {   
       return sqlMapClient;   
   }   
}

然后改成:
public class DB {
  private  SqlMapClient sqlMapClient;   
   
   //指定 ibatis配置文件的路径    
   private  String path = "/OracleMapConfig.xml";
   java.io.Reader reader = null;
   
   public SqlMapClient GetSqlMap() {  
       try {   
           //初始,加载配置文件   
        System.out.println("path ==== " + path);
           reader = com.ibatis.common.resources.Resources.getResourceAsReader(path);   
           sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);   
           sqlMapClient.getCurrentConnection();
           reader.close();
       } catch (Exception ex) { 
        System.out.println("加载配置文件失败!");
           ex.printStackTrace();   
       }  
       return sqlMapClient;   
   }   
}


需要用的就new DB,不知道对不对,测试环境也没这个条件,如果还不解决的话,明天就要开会被当活靶子射了,哎,命苦!各位帮帮啊,小弟不胜感激。

#3


因为配置了空闲连接的超时时间。。。所以导致了你上面的情况。。。可以肯定的是,你的问题就是因为这个。。。。上次好像也遇到一个朋友,遇到这种问题。。。

#4


配置空闲连接超时时间?这个会有问题吗