我在代码中看到一个奇怪的行为。我正在使用Spring DI获取连接。以下是我的ibatis-context.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@hostname:port:dbname" />
<property name="username" value="$usrname" />
<property name="password" value="$pwd" />
<property name="initialSize" value="1"/>
<property name="maxActive" value="1"/>
<property name="maxIdle" value="1"/>
<property name="testWhileIdle" value="true"/>
<property name="minEvictableIdleTimeMillis" value="500"/>
<property name="timeBetweenEvictionRunsMillis" value="500"/>
<property name="validationQuery" value="select 1 from dual"/>
</bean>
当我执行第一个查询时,它返回ResultSet。但是当我使用相同的连接执行第二个查询时,它会抛出我的错误(java.sql.SQLException:已经关闭)。
code
try {
// First Query
personList = sqlMap.queryForList("getPersonList", parameterMap);
} catch (Exception e) {
e.printStackTrace();
}
try {
// Second Query
firstNameList = sqlMap.queryForList("getfirstNameList", parameterMap);
} catch (Exception e) {
e.printStackTrace();
}
相同的代码和配置几天前工作正常,但现在我收到错误 问题的堆栈跟踪。
java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:191)
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:278)
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:160)
at $Proxy10.close(Unknown Source)
at com.ibatis.sqlmap.engine.transaction.external.ExternalTransaction.close(ExternalTransaction.java:82)
at com.ibatis.sqlmap.engine.transaction.TransactionManager.end(TransactionManager.java:93)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.endTransaction(SqlMapExecutorDelegate.java:734)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.endTransaction(SqlMapSessionImpl.java:176)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.endTransaction(SqlMapClientImpl.java:153)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.autoEndTransaction(SqlMapExecutorDelegate.java:835)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:574)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:541)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:94)
at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
是代码问题还是数据库问题?
有人有解决方案吗?
答案 0 :(得分:1)
我找到了问题的根本原因
上面给出的配置没有问题
问题是第二个查询(这是一个无效的查询与不适当的连接),oracle抛出内部错误,连接关闭。
当我在SQLDeveloper(UI查询工具)中执行查询时,oracle抛出错误并关闭会话。
ORA-00600: internal error code, arguments: [kkqcscpopn_Int: 0], [], [], [], [], [], [], [], [], [], [], []
00600. 00000 - "internal error code, arguments: [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s]"
*Cause: This is the generic internal error number for Oracle program
exceptions. This indicates that a process has encountered an
exceptional condition.
*Action: Report as a bug - the first argument is the internal error number
有关错误的更多信息位于以下链接中。 http://www.orafaq.com/wiki/ORA-00600
总之,查询中的不当连接可能是此错误的原因之一(java.sql.SQLException:已经关闭)。
因此,最好仔细检查查询并继续进行。
答案 1 :(得分:0)
TL; DR;如果看到此异常,则表示数据库驱动程序关闭了连接,通常是由于IOException级别失败。检查你的日志; IBatis可能已经为您记录了例外情况。如果没有池没有运行相同的命令,你会看到真正的异常。
这里的问题是在finally子句期间公共池实现抛出了“已经关闭”的异常,并隐藏了真正的异常。在解决JTDS驱动程序的问题时,我遇到了同样的问题。我相信最直接的解决方法是在finally块中的connection.close周围添加一个try / catch。由于iBatis 2.3.x流基本上已经死了,除了尝试其他池实现之外,我没有一个很好的解决方案来解决这个问题。