java.sql.SQLException:IBatis 2.3.4已经关闭错误

时间:2012-08-23 05:33:14

标签: oracle ibatis weblogic-10.x

我在代码中看到一个奇怪的行为。我正在使用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)

是代码问题还是数据库问题?
有人有解决方案吗?

2 个答案:

答案 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流基本上已经死了,除了尝试其他池实现之外,我没有一个很好的解决方案来解决这个问题。