xuwenjin 2008-06-24 17:56
浏览 205
已采纳

resin 数据池被占满问题

环境linux,apache,resin,oracle
一直运行很好,最近老是出现java.sql.SQLException: Can't open connection with full database pool (20)
打开进程一看,oracle进程一堆。是resin连接池被占满了。
把resin重启后,数据池立即又被占满了。

不知道是什么原因。
请朋友门赐教。可能是哪方面的原因。该如何查起了。

[b]问题补充:[/b]
waterdh (初级程序员) 检查数据库连接代码,看哪里没有释放连接

不知道该从哪下手,数据库连接代码是公用的,很多地方使用到了,该从哪下手了。郁闷。

  • 写回答

3条回答 默认 最新

  • llade163 2008-06-25 01:40
    关注

    有一个比较简便的方法可以跟踪哪些数据库连接没有释放,就是做一个代理类,这个代理类自己有个超时机制,超时没有释放的则打印调用堆栈。
    使用的时候要将这个伪装的DataSource打包成JAR放在resin的库目录(因为你在resin配置了连接池)
    以下是这个代理类的部分代码,有兴趣的话,你自己补全即可。希望有所帮助。GOOD LUCK
    [code="java"]package com.poweroa.jdbc;

    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.sql.SQLWarning;
    import java.sql.Savepoint;
    import java.sql.Statement;
    import java.util.Map;
    import java.util.Timer;
    import java.util.TimerTask;

    import org.apache.commons.dbcp.BasicDataSource;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class MyDataSource extends BasicDataSource {//此处使用apache的dbcp,你实际Resin环境使用的是什么DataSource就继承它,注意有些连接池是final类,不可被继承,所以尽量使用dbcp做测试。

    public final static Timer timer = new Timer(true);//定时器,用来运行Connection记录超时的代理。
    
    Log logger = LogFactory.getLog(MyDataSource.class);//log4j的使用就不必说了吧。
    class ProxyConnection implements Connection{//本dataSource getConnection方法返回的代理Connection对象
    
        Connection innnerConnection;//实际的连接池里的连接
        String uuid;
        TimerTask task;
    
        public ProxyConnection(Connection conn,String uuid){
            task=new TimerTask(){
    
                @Override
                public void run() {//里面的代码是堆栈跟踪用的,所以那么奇怪,自己抛出异常又自己捕捉了。
                    try {
                        throw new RuntimeException();
                    } catch (RuntimeException e) {
                        logger.debug(e);//其实log4j作用不大,只是写习惯了。就加上吧。
                        e.printStackTrace();//这句能清楚的打印出调用堆栈。
                    }
                }
    
            };
            timer.schedule(task, 5000);//设置其5秒后运行,根据你环境实际情况设置,假如你觉得5秒不够,那就10秒,也就是说10秒还不释放此连接则超时。
            this.innnerConnection=conn;
            this.uuid=uuid;
        }
    
        public void clearWarnings() throws SQLException {
            this.innnerConnection.clearWarnings();
        }
    
        public void close() throws SQLException {
            this.task.cancel();//如果在指定时间内关闭了连接,则取消定时,表示此时调用代码正常关闭了连接,不必跟踪。
            this.innnerConnection.close();
        }
    
        public void commit() throws SQLException {
            this.innnerConnection.commit();
        }
    

    //.....此处省略其他Connection接口的方法没有列出来。你自己必须实现它们,
    //方法内部只有一句:this.innnerConnection.xxx();
    }
    //下面是DataSource接口仅有的两个返回Connection对象的方法。都需要覆盖掉,使得返回代理的Connection
    @Override
    public Connection getConnection() throws SQLException {

        Connection conn=super.getConnection();
         return new ProxyConnection(conn,java.util.UUID.randomUUID().toString());
    }
    
    @Override
    public Connection getConnection(String user, String password) throws SQLException {
        Connection conn=super.getConnection(user,password);
        if(conn instanceof ProxyConnection)return conn;
        return new ProxyConnection(conn,java.util.UUID.randomUUID().toString());
    }
    
    }[/code]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?