c3p0 连接无法释放

peanutmain 发布于 2012/08/19 17:38
阅读 18K+
收藏 0

最近有个小项目,struts2 + jdbc,用了c3p0的连接池,发现每当使用的连接数总和超过最大连接数就死了,即获取不到connection,如果c3p0设置了checkoutTimeout,则会抛出An attempt by a client to checkout a Connection has timed out.异常,在网上找了一下午资料,大致是使用过的连接没有被释放掉,该怎么解决呢

连接池代码如下:

import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class ConnectionPool {
		private static class SingletonHolder {
			static ConnectionPool instance = new ConnectionPool();
		}
	    static final String configFile = "c3p0.properties";
	    private static ComboPooledDataSource ds;
	    private static int i =1;

	    /**
		 * 得到一个连接池实例
		 * 
		 * @return 
		 */
		public static ConnectionPool getInstance() {
			return SingletonHolder.instance;
		}

		/**
	     * 初始化连接池配置
	     */
	    private ConnectionPool() {
	    	 try {
		            Properties p = new Properties();
		            InputStream is = ConnectionPool.class.getClassLoader()
		                    .getResourceAsStream(configFile);
		            p.load(is);
		            ds = new ComboPooledDataSource();
		            try {
		                ds.setDriverClass((String) p.get("database.driverClassName"));
		            } catch (PropertyVetoException e) {
		                e.printStackTrace();
		            }
		            ds.setJdbcUrl((String) p.get("jdbc.url"));
		            ds.setUser((String) p.get("jdbc.username"));
		            ds.setPassword((String) p.get("jdbc.password"));
		            ds.setInitialPoolSize(Integer.parseInt((String) p
		                    .get("initialPoolSize")));
		            ds.setMaxPoolSize(Integer.parseInt((String) p.get("maxPoolSize")));
		            ds.setMinPoolSize(Integer.parseInt((String) p.get("minPoolSize")));
		            ds.setAcquireIncrement(Integer.parseInt((String) p.get("acquireIncrement")));
		            ds.setAutoCommitOnClose(Boolean.parseBoolean((p
		                    .get("autoCommitOnClose").toString())));
		            ds.setMaxIdleTime(Integer.parseInt(p.getProperty("maxIdleTime")));
		            ds.setAcquireRetryDelay(Integer.parseInt((String) p.get("acquireRetryDelay")));
		            ds.setBreakAfterAcquireFailure(Boolean.parseBoolean((p
		                    .get("breakAfterAcquireFailure").toString())));
		            ds.setCheckoutTimeout(Integer.parseInt((String) p.get("checkoutTimeout")));
		            ds.setIdleConnectionTestPeriod(Integer.parseInt((String) p.get("idleConnectionTestPeriod")));
		            ds.setNumHelperThreads(Integer.parseInt((String) p.get("numHelperThreads")));
		            ds.setPropertyCycle(Integer.parseInt((String) p.get("propertyCycle")));
		            ds.setMaxStatements(Integer.parseInt((String) p.get("maxStatements")));
		            ds.setDebugUnreturnedConnectionStackTraces(true);
	    	 } catch (IOException e) {
		            e.printStackTrace();
		        }
	    }

		/**
		 * 获得一个连接
		 * 
		 * @return 
		 * @throws SQLException
		 */
		public Connection getConnection() {
			try {
				System.out.println(i++);
				return ds.getConnection();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return null;
		}
		
}

c3p0具体配置文件如下:

####################    数据库连接设置 ###########################
database.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3309/db
jdbc.username=root
jdbc.password=root
#####################   C3p0 连接池配置  #####################
# 始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。默认为3
initialPoolSize=20
# 接池中保留的最大连接数。默认为15
maxPoolSize=30
minPoolSize=20
# 当连接池中的连接用完时,C3P0一次性创建新连接的数目 默认 3
acquireIncrement=10
# 定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30
acquireRetryAttempts=100
# 两次连接中间隔时间,单位毫秒,默认为1000
acquireRetryDelay=1000
# 连接关闭时默认将所有未提交的操作回滚。默认为false
autoCommitOnClose=false
# 获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留,并在下 
# 次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接
# 失败后该数据源将申明已断开并永久关闭。默认为false
breakAfterAcquireFailure=false
# 当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出    
# SQLException,如设为0则无限期等待。单位毫秒,默认为0
checkoutTimeout=20000
# 最大空闲时间,超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0
maxIdleTime=60
# 每60秒检查所有连接池中的空闲连接。Default: 0
idleConnectionTestPeriod=60
# C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 
#通过多线程实现多个操作同时被执行。默认为3
numHelperThreads=3
# 用户修改系统配置参数执行前最多等待的秒数。默认为300
propertyCycle=300
maxStatements=0

 

 

 

 

加载中
0
JFinal
JFinal
    在 finally 块中关闭数据库连接,保障连接都被关闭,建议你看看 @JFinal 中的 com.jfinal.plugin.activerecord.Model 或者 Db.java,同样使用的 c3p0 未出现楼出的情况。
0
peanutmain
peanutmain
还是得靠自己啊,呵呵,解决了,是个小问题,反应出自己多粗心啊,基础欠缺
0
k
kari
楼主分享一下啊,最近也碰到了c3p0连接池无法释放的情况。
peanutmain
peanutmain
呵呵,是我自己没有close掉connection的问题,你仔细检查检查吧,看是不是此问题
0
0
张韬1
getConnection() 方法中少了finally 里面关闭方法。
CoderLeonard
CoderLeonard
在getConnection()里面用finally关闭连接吗?这个方法不是用来获取连接的吗?
返回顶部
顶部