0

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

当我执行第一个查询时,它会返回结果集。但是当我使用相同的连接执行第二个查询时,它会抛出错误(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)

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

4

2 回答 2

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:已关闭)。
因此,最好仔细检查查询并继续进行。

于 2012-08-24T11:09:17.970 回答
0

TL;博士; 如果您看到此异常,则意味着您的数据库驱动程序关闭了连接,通常是由于 IOException 级别的故障。检查您的日志;IBatis 可能已经为您记录了异常。如果没有在没有池的情况下运行相同的命令,您将看到真正的异常。

这里的问题是公共池实现在 finally 子句期间抛出了“已经关闭”的异常,并隐藏了真正的异常。在解决 JTDS 驱动程序的问题时,我遇到了同样的问题。我相信最直接的解决方法是在 finally 块中的 connection.close 周围添加一个 try/catch。由于 iBatis 2.3.x 流基本上已经死了,除了尝试其他池实现之外,我没有很好的解决方案来解决这个问题。

于 2013-05-22T14:03:25.673 回答