最近有个项目使用了proxool连接池,感觉它的配置很简单。
把相关的JAR包放入项目中,然后自己建一个xml<?xml version="1.0" encoding="UTF-8"?>
<something-else-entirely>
<proxool>
<alias>test</alias>
<driver-url>jdbc:sqlserver://localhost:1433;DatabaseName=wz</driver-url>
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<driver-properties>
<property name="user" value="aa"/>
<property name="password" value="aa"/>
</driver-properties>
<house-keeping-sleep-time>30000</house-keeping-sleep-time>
<maximum-new-connections>10000</maximum-new-connections>
<prototype-count>200</prototype-count>
<maximum-connection-count>5000</maximum-connection-count>
<minimum-connection-count>100</minimum-connection-count>
<maximum-active-time>60000</maximum-active-time> 
<house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
</proxool>
</something-else-entirely>然后在web.xml里加入 <servlet>
<servlet-name>ServletConfigurator</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/admin/proxool/</url-pattern>
</servlet-mapping>

解决方案 »

  1.   


    public class DBConnection {       private static Connection conn = null;
       
         public DBConnection(){          
              }       
                    
         
         /**   
          * 取得连接池中的连接   
          * @return   
          */    
         public static Connection getConnection() {    
      try {
    conn = DriverManager.getConnection("proxool.test");
    System.out.println(conn+"*****************************");
    return conn;
    } catch (SQLException e) {
    System.out.println("getConn:"+e.getMessage());
    return null;
    }
         }    
            
         /**  
          * 释放连接  
          * freeConnection  
          * @param conn  
          */  
         public static void freeConnection(Connection conn){   
             if(conn != null){   
                 try {   
                     conn.close();   
                 } catch (SQLException e) {                 
                     e.printStackTrace();   
                 }   
             }   
         }   
       
     }
    这是连接类。
    连接是好的。但是我在用到JSP页面,按F5连续刷的时候,会报错误java.sql.SQLException: Couldn't perform the operation prepareStatement: You can't perform a prepareStatement operation after the connection has been closed但页面还是能用的。为什么会报这个错误呢
    在日志中还会报这个错2008-11-28 10:38:42 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
    java.lang.OutOfMemoryError: Java heap space2008-11-28 10:38:42 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
    java.lang.OutOfMemoryError: Java heap space2008-11-28 10:38:42 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
    java.lang.OutOfMemoryError: Java heap space另外网上说可以查看连接情况,但是我怎么就打不开那个页面呢
    http://localhost:8080/admin/proxool/
    报404错误
      

  2.   

    1.404页面路径有问题么?
    2.You can't perform a prepareStatement operation after the connection has been closed
      连接关了
      

  3.   

    proxool-0.9.0RC3.jar这是我用的版本。
      

  4.   


    /**
     * 根据ID得到投票选项名称
     * @param id
     * @return 投票选项名称
     * @throws Exception
     */
    public String getVoteClassNameById(String id) throws Exception {
    conn = DBConnection.getConnection();
    String className = "";
    sql = "select CLASS_NAME from VOTE_CLASS_NAME where DELETE_FLAG=1 and ID=?";
    try{
    ps = conn.prepareStatement(sql);
    ps.setString(1, id);
    rs = ps.executeQuery();
    while(rs.next()){
    className = rs.getString("CLASS_NAME");
    }
    }catch(Exception e){
    e.printStackTrace();
    }finally{
    if(rs!=null){
    rs.close();
    }
    if(ps!=null){
    ps.close();
    }
    DBConnection.freeConnection(conn);
    }
    return className;
    }这是其中一个方法,所有的方法都是以这种形式关闭连接的。
      

  5.   

    finally{
                if(rs!=null){
                    rs.close();
                }
                if(ps!=null){
                    ps.close();
                }
                DBConnection.freeConnection(conn);
            }
            return className;
    老大,你都关闭连接了还能返回去吗?
    将return className提前到finally前试试
      

  6.   

    程序没看出太大的问题。但是OutOfMemery了,估计是你的最大连接数太设多了,把配置文件中的
    <maximum-connection-count>5000</maximum-connection-count>
    <minimum-connection-count>100</minimum-connection-count>
    改成
    <maximum-connection-count>50</maximum-connection-count>
    <minimum-connection-count>10</minimum-connection-count>
    再试
      

  7.   

    另外,代码最好这样写:        try {
                conn = DriverManager.getConnection("proxool.property-test");
                pstmt = conn.prepareStatement();
           
                rs = pstmt.executeQuery();
                //处理代码
            }
            catch( SQLException sqle ) {
                sqle.printStackTrace();
            }
            finally {
                try {  pstmt.close(); }
                catch (Exception e) { e.printStackTrace(); }
                try {  conn.close();   }
                catch (Exception e) { e.printStackTrace(); }
            }
      

  8.   

    把数值降低点试试
    毕竟出现OOM问题了
      

  9.   

    我把连接数给减少之后,然后连续刷页面,直接给刷挂了。平台报如下错误。2008-11-28 13:15:27 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
    严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.tomcat.util.net.TcpWorkerThread@439d3b, terminating thread
      

  10.   

    我这个测试页面就调用了一个方法。 /**
     * 根据SQL语句得到总的记录
     * @param sql
     * @return 得到总的记录
     * @throws Exception
     */
    public List findAllVoteNameInfoList(String sql) throws Exception {
            conn = DBConnection.getConnection();
            dataList = new ArrayList();
            try{
             ps = conn.prepareStatement(sql);
             rs = ps.executeQuery();
             while(rs.next()){
             model = new VoteNameModel();
             model.setClassId(rs.getString("CLASS_ID"));
             model.setCreateUserNo(rs.getString("CREATE_USER_NO"));
             model.setDeleteFlag(rs.getInt("DELETE_FLAG"));
             model.setId(rs.getInt("ID"));
             model.setUpdateDateTime(rs.getString("UPDATE_DATE_TIME"));
             model.setUpdateUserNo(rs.getString("UPDATE_USER_NO"));
             model.setVoteName(rs.getString("VOTE_NAME"));
             model.setVoteFlag(rs.getInt("VOTE_FLAG"));
             dataList.add(model);
             }
            }catch(Exception e){
             e.printStackTrace();
            }finally{
             if(rs!=null){
             rs.close();
             }
             if(ps!=null){
             ps.close();
             }
             DBConnection.freeConnection(conn);
            }
    return dataList;
    }
      

  11.   

    顶。
        <servlet>
            <servlet-name>ServletConfigurator</servlet-name>
            <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
            <init-param>
                <param-name>xmlFile</param-name>
                <param-value>WEB-INF/proxool.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet>
            <servlet-name>Admin</servlet-name>
            <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>Admin</servlet-name>
            <url-pattern>/admin/proxool/</url-pattern>
        </servlet-mapping>
      

  12.   

    以前我们做了个数据库连接池,属于通用的那种,需要的话,告诉我MSN或邮箱地址。
      

  13.   

    我在网上查的时候,这个proxool评价挺好的。可能是我的代码哪有问题,可是又发现不了什么问题?狂郁闷。
      

  14.   

    DBConnection.freeConnection(conn); conn 是 所有类共享的吧!static Connectionconn资源连接释放了!可是对象还有引用。连接释放也是有延时的!根本快不过你那连续的F5.原来写在ACTION中可以形成高速缓存,但执行方法是线程安全的,可以在执行方法中写获取连接,对应的是servlet 方式。
    -------------------------------------------------------------------------------------------
    我是瞎蒙的,不要相信我!!
      

  15.   

    在楼上的提示下看出代码的问题了:
    就是DBConnection类
    它用了一个静态的值保存conn,这种做法是严重错误的!
    第一个请求者来调用它,它从连接池里面得到一个conn1,把它放到这个静态变量;
    假设第一个请求者还未释放,第二个请求来了,它又放的是conn2;
    如果第一个请求调用Free,那么它释放的是conn2,这时候如果conn2使用prepareStatement,因为conn2已经被你close了,所以它就会报错:
    You can't perform a prepareStatement operation after the connection has been closed
    而第一个conn1根本就没被释放,这样次数多了,就会导致OutOfMemery解决方案:
    不要DBConnection类,在需要conn的时候,直接用
    conn = DriverManager.getConnection("proxool.property-test");
    关闭是直接用:
    conn.close();
      

  16.   

    要也可以,毕竟有一点好处:如果你的配置文件中连接池的Alias改了,不用到处找对应的地方改。
    但不能这样写,可以这样:public class DBConnection {     
         public static Connection getConnection() { 
            Connection conn=null;
            try {
                conn = DriverManager.getConnection("proxool.test");
                System.out.println(conn+"*****************************");
                return conn;
            } catch (SQLException e) {
                System.out.println("getConn:"+e.getMessage());
            }
            return conn;
         }    
    }连接时就调用这个静态方法;释放还是直接用conn.close();
      

  17.   

    你现在测试的
    连接数的XML的设置是多少
      

  18.   


    <?xml version="1.0" encoding="UTF-8"?>
    <something-else-entirely>
    <proxool>
    <alias>test</alias>
    <driver-url>jdbc:sqlserver://localhost:1433;DatabaseName=wz</driver-url>
    <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
    <driver-properties>
    <property name="user" value="aa"/>
    <property name="password" value="aa"/>
    </driver-properties>
    <house-keeping-sleep-time>30000</house-keeping-sleep-time>
    <maximum-new-connections>100</maximum-new-connections>
    <prototype-count>200</prototype-count>
    <maximum-connection-count>50</maximum-connection-count>
    <minimum-connection-count>10</minimum-connection-count>
    <maximum-active-time>60000</maximum-active-time> 
    <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
    </proxool>
    </something-else-entirely>
      

  19.   

    这是我以前在网上收集的,我也用过是可以的:
    proxool.xml
    <something-else-entirely>
      <proxool>
    <alias>testpool</alias> <driver-url>jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=TestSql;SelectMethod=cursor</driver-url>
    <driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class> <driver-properties>
    <property name="user" value="sa"/>
    <property name="password" value=""/>
    </driver-properties> <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁-->
    <house-keeping-sleep-time>300000</house-keeping-sleep-time>
    <!--最大的等待请求数,即因没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->
            <proxool.simultaneous-build-throttle>200</proxool.simultaneous-build-throttle>
    <!-- maximum-new-connections>50</maximum-new-connections-->
     <!-- 最少保持的空闲连接数-->
    <prototype-count>5</prototype-count>
    <!-- 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定-->
    <maximum-connection-count>100</maximum-connection-count>
      <!-- 最小连接数-->
    <minimum-connection-count>20</minimum-connection-count>
    <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql> </proxool>
    </something-else-entirely>
    web.xml
    <servlet>
        <servlet-name>ServletConfigurator</servlet-name>
        <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
        <init-param>
          <param-name>xmlFile</param-name>
          <param-value>/WEB-INF/classes/proxool.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet>
        <servlet-name>proxool</servlet-name>
        <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
      </servlet>
    Java,我也是用静态的!
      

  20.   

    就是打不开页面,平台报内存溢出错误java.lang.OutOfMemoryError: Java heap space//日志报的错
      

  21.   


    你把findAllVoteNameInfoList这个类,整个文件都给我看。
    还有调用这个方法的类的整个代码
      

  22.   

    Properties 下面是全部的属性列表:fatal-sql-exception: 它是一个逗号分割的信息片段.当一个SQL异常发生时,他的异常信息将与这个信息片段进行比较.如果在片段中存在,那么这个异常将被认为是个致命错误(Fatal SQL Exception ).这种情况下,数据库连接将要被放弃.无论发生什么,这个异常将会被重掷以提供给消费者.用户最好自己配置一个不同的异常来抛出.fatal-sql-exception-wrapper-class:正如上面所说,你最好配置一个不同的异常来重掷.利用这个属性,用户可以包装SQLException,使他变成另外一个异常.这个异常或者继承SQLException或者继承字RuntimeException.proxool自带了2个实现:'org.logicalcobwebs.proxool.FatalSQLException' 和'org.logicalcobwebs.proxool.FatalRuntimeException' .后者更合适.house-keeping-sleep-time: house keeper 保留线程处于睡眠状态的最长时间,house keeper 的职责就是检查各个连接的状态,并判断是否需要销毁或者创建.house-keeping-test-sql:  如果发现了空闲的数据库连接.house keeper 将会用这个语句来测试.这个语句最好非常快的被执行.如果没有定义,测试过程将会被忽略。injectable-connection-interface: 允许proxool实现被代理的connection对象的方法.injectable-statement-interface: 允许proxool实现被代理的Statement 对象方法.injectable-prepared-statement-interface: 允许proxool实现被代理的PreparedStatement 对象方法.injectable-callable-statement-interface: 允许proxool实现被代理的CallableStatement 对象方法.jmx: 略jmx-agent-id: 略jndi-name: 数据源的名称maximum-active-time: 如果housekeeper 检测到某个线程的活动时间大于这个数值.它将会杀掉这个线程.所以确认一下你的服务器的带宽.然后定一个合适的值.默认是5分钟.maximum-connection-count: 最大的数据库连接数.maximum-connection-lifetime: 一个线程的最大寿命.minimum-connection-count: 最小的数据库连接数overload-without-refusal-lifetime: 略prototype-count: 连接池中可用的连接数量.如果当前的连接池中的连接少于这个数值.新的连接将被建立(假设没有超过最大可用数).例如.我们有3个活动连接2个可用连接,而我们的prototype-count是4,那么数据库连接池将试图建立另外2个连接.这和 minimum-connection-count不同. minimum-connection-count把活动的连接也计算在内.prototype-count 是spare connections 的数量.recently-started-threshold:  略simultaneous-build-throttle:  略statistics: 略statistics-log-level:  略test-before-use: 略test-after-use: 略trace: 如果为true,那么每个被执行的SQL语句将会在执行期被log记录(DEBUG LEVEL).你也可以注册一个ConnectionListener (参看ProxoolFacade)得到这些信息.verbose: 略.alias                     -〉数据库连接别名(程序中需要使用的名称)
    driver-url                -〉数据库驱动
    driver-class                -〉驱动程序类
    driver-properties            -〉联机数据库的用户和密码
    minimum-connection-count     -〉最小连接数量,建议设置0以上,保证第一次连接时间
    maximum-connection-count      -〉最大连接数量,如果超过最大连接数量则会抛出异常。连接数设置过多,服务器CPU和内存性能消耗很大。
    simultaneous-build-throttle     -〉同时最大连接数
    prototype-count                -〉一次产生连接的数量。
                                    例:如果现在prototype-count设置为4个,但是现在已经有2个可以获得的连接,那么将会试图再创建2个连接。
                                                      但不能超过最大连接数。
    maximum-active-time          -〉连接最大时间活动 默认5分钟
    maximum-connection-lifetime      -〉连接最大生命时间 默认4小时
      

  23.   

    关闭的时候直接关闭就OK了,直接调用con.close(),连接不关闭你的连接池一会就满了,报异常是因为你设置的连接太多了,你把每个连接maximum-active-time 设置的小点,设置成1分钟看看啦,
    看连接状态需要到这个地址 http://127.0.0.1:****/***/admin 访问的
      

  24.   

    proxool-0.9.0RC3.jar 这个jar是需要你改的,因为中文问题,具体看这里
      

  25.   

    我觉得问题在于,你执行数据库操作时获取的conn不是局部变量。
    就是这一句:conn = DBConnection.getConnection();
    当你连续F5刷新的时候,servlet是多线程处理的。可能线程1运行到 ps = conn.prepareStatement(sql);的时候,线程2已经把conn关闭了。
    楼主试一下在获取连接和释放连接的地方打印日志,看看。
      

  26.   

    除了我在60楼说的servelt里使用conn的问题。
    DBConnection 类也有问题。
    下面这行要去掉。
         private static Connection conn = null;getConnection() 方法直接返回一个新的变量。
     public static Connection getConnection() {    
             try {
                Connection conn = DriverManager.getConnection("proxool.test");
                System.out.println(conn+"*****************************");
                return conn;
            } catch (SQLException e) {
                System.out.println("getConn:"+e.getMessage());
                return null;
            }
         }   
      

  27.   

    我没用过你那种方式啊,不过我自己用Java写过这样的例子啊,你那配置也多,不只速度是否良好啊。
      

  28.   

    我怎么觉得proxool连接池技术还没有JDBC连接稳定呀。我有一个项目是用JDBC连的,我连续刷三四分钟,有报错误,但是还是可以打开页面的,但是我换成了proxool却不行,连续刷个三四分钟,就爆内存溢出了,页面就打不开。怎么回事呀????应该不是代码的问题呀,难道proxool连接池技术不好吗????
      

  29.   

    谁有成功配置proxool这个的经验,不是单纯的配置成功,而是性能非常好,比如连续刷没问题的。
      

  30.   

    现在好像可以了,我把TOMCAT重装了之后,连续刷就没有问题了,怎么回事?????
    之前我跑过很多项目的,是不是因为什么有冲突呀。
      

  31.   

    楼主,你可以试一下,在你的public String getVoteClassNameById(String id) throws Exception {
            conn = DBConnection.getConnection();
    后面Sleep 10秒。
    在这10秒内刷一下页面。让几个线程都执行到Sleep。然后等第一个线程被唤醒后执行sql,最后释放conn。之后其他几个线程被唤醒,再执行sql,就该报错了。
      

  32.   

    连续刷要看你设置好不,我上面说的很清楚了,maximum-active-time 设置成10秒钟你试试看,连接池随便设置个40~50个,让你刷去,只要不是手一直按在F5上,就能保证这个连接始终是够用的
    真正用到具体项目上要看具体应用,你说一天大概是2.5万并不是准确数字,你应该说是 在什么时候 登陆最多人是多少,一个人登陆的时候 一个连接的时间是多长,这样才能设置够用,就比如说是一个考试系统,考生一起准时登陆,那么这个时候多少个考生就是一个比较实在的数字,你连接池的数目要够这些人同时登陆使用,其实人们也不是很准确的在同一个时间登陆的,所以又要看你这一个连接需要连接多长时间。
    如果出现异常情况 一般需要多长时间恢复,maximum-active-time 就是如果超过这个时间 连接池会自动给你断开,而不管你的用户连接了,生生的吧连接收回了
    用不好不能说他不好
      

  33.   

    proxool-0.9.0RC3.jar 这个jar是需要你改的,因为中文编码问题,上面有说,具体看那个连接,你内存溢出是因为你有地方连接没关闭 而你连接数又设置过多的问题