【发布时间】:2016-01-13 12:43:15
【问题描述】:
我正在使用 Maven 在 Tomcat 8 上开发一个 Web 应用程序,我正在使用 c3p0 来处理主线程和其他 2 个并发线程上的连接,我的连接管理器类正在询问我已经实现的 DataSource 单例类同步连接,像这样
public synchronized Connection getConnection() {
try {
return cpds.getConnection();
} catch (SQLException ex) {
logger.error("Error while issuing a pooled connection", ex);
}
return null;
}
,但是当我尝试使用这些连接时,它们会开始中断
09:47:17.164 [QuartzScheduler_Worker-4] ERROR com.myapp.providers.DataSource - Error while issuing a pooled connection
java.sql.SQLException: An SQLException was provoked by the following failure: java.lang.InterruptedException
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2]
或在事务中间关闭并破坏当时正在使用的任何语句和结果集
我正在像这样配置 DataSource 对象
cpds = new ComboPooledDataSource();
cpds.setDriverClass(oracle.jdbc.driver.OracleDriver);
cpds.setJdbcUrl(jdbc:oracle:thin:@xx.xxx.xxx.xxx:1521:XE);
cpds.setUser("username");
cpds.setPassword("password");
// database connection properties
cpds.setInitialPoolSize(10);
cpds.setAcquireIncrement(3);
cpds.setMaxPoolSize(100);
cpds.setMinPoolSize(15);
cpds.setMaxStatements(75);
// connection pool preferences
cpds.setIdleConnectionTestPeriod(60);
cpds.setMaxIdleTime(30000);
cpds.setAutoCommitOnClose(false);
cpds.setPreferredTestQuery("SELECT 1 FROM DUAL");
cpds.setTestConnectionOnCheckin(false);
cpds.setTestConnectionOnCheckout(false);
cpds.setAcquireRetryAttempts(30);
cpds.setAcquireRetryDelay(1000);
cpds.setBreakAfterAcquireFailure(false);
我还编写了一个小测试方法,它在循环中运行并查询数据库 n 次,但效果很好。
【问题讨论】:
-
你的 crp0 配置在哪里?
-
我正在以编程方式对其进行配置,我将在几秒钟内对其进行编辑
-
在@Steve Waldman 的回答中,他指向了一个已挂起的线程,那么您是否使用不同的线程打开连接并使用连接?如果你在一个线程中使用连接,当另一个线程从池中请求连接时,它不知道上下文(意味着 tomcat 不知道它的存在),tomcat 会积极地中断第一个线程以将连接传递给第二个线程
-
这不是一个新项目,我也没有在这两个线程上完成所有工作。在某些情况下,我会在 Jersey2 端点中打开一个连接(即返回 GET 响应)