Java 处理后,Resultset和CallableStatement未关闭
我试图在处理后关闭Java 处理后,Resultset和CallableStatement未关闭,java,oracle,jdbc,Java,Oracle,Jdbc,我试图在处理后关闭ResultSet和CallableStatement,但只有Connection正在关闭,其他两个没有关闭 final String procedureCall = "{call GET_PAWS_PERSON_DETAILS(?, ?)}"; try { //Get Connection instance from dataSource connection = dataSource.getConnection();
ResultSet
和CallableStatement
,但只有Connection
正在关闭,其他两个没有关闭
final String procedureCall = "{call GET_PAWS_PERSON_DETAILS(?, ?)}";
try {
//Get Connection instance from dataSource
connection = dataSource.getConnection();
callableStatement = connection.prepareCall(procedureCall);
callableStatement.setString(1, userName);
callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
//Call Stored Procedure
callableStatement.executeUpdate();
// get cursor and cast it to ResultSet
resultSet = (ResultSet) callableStatement.getObject(2);
logger.debug("reslt" + resultSet.getFetchSize());
// loop it like normal
while (resultSet.next()) {
personDTO.setPersonID(resultSet.getString(1));
personDTO.setFirstName(resultSet.getString(2));
personDTO.setLastName(resultSet.getString(3));
personDTO.setFullName(resultSet.getString(4));
personDTO.setEmail(resultSet.getString(5));
}
}catch (SQLException e) {
e.printStackTrace();
} finally {
if(resultSet != null)
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(callableStatement != null)
try {
callableStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(connection != null)
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
这是我正在使用的代码。关闭后,只需打印连接
,状态
和可调用状态
。结果是
Connection : null
Resultset : org.apache.tomcat.dbcp.dbcp.DelegatingResultSet@6f1f6b1e
Callable statement : oracle.jdbc.driver.OracleStatementWrapper@77b1b790.
由于此问题,数据库连接池的大小正在增加
请给我任何人的解决方案
在Tomcat server.xml中
<Resource driverClassName="oracle.jdbc.OracleDriver" maxActive="4" maxIdle="10" maxWait="5000" name="jdbc/epaws" global="jdbc/epaws"
password="polusneu" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.1.60:1521:coeusnew"
username="polusneu" validationQuery="select 1 from dual" testOnBorrow="true" removeAbandoned="true"
removeAbandonedTimeout="55"/>
applicationcontext.xml
<bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/epaws"/>
<property name="resourceRef" value="true"/>
<property name="cache" value="false"/>
<property name="lookupOnStartup" value="false"/>
<property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>
首先:
关闭对象不会将该对象引用设置为null
。所以在结束后你仍然有物体是可以的。但奇怪的是,在。。。但无论如何
最后关闭
块是一个有效的过程,但这是一个老派的过程。Java7引入了一个很棒的新特性,名为trytwithresource
,它负责关闭,即使是在出现错误的情况下。然后代码看起来像
try(Connection con = dataSource.getConnection();
CallableStatement callable = con.prepareCall(procedureCall)) {
callableStatement.setString(1, userName);
callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
//Call Stored Procedure
callableStatement.executeUpdate();
// get cursor and cast it to ResultSet
try(ResultSet resultSet = (ResultSet) callableStatement.getObject(2)) {
logger.debug("reslt" + resultSet.getFetchSize());
// loop it like normal
while (resultSet.next()) {
personDTO.setPersonID(resultSet.getString(1));
personDTO.setFirstName(resultSet.getString(2));
personDTO.setLastName(resultSet.getString(3));
personDTO.setFullName(resultSet.getString(4));
personDTO.setEmail(resultSet.getString(5));
}
} //Don't need another catch
} catch(SQLException e) {
e.printStackTrace();
}
首先:
关闭对象不会将该对象引用设置为null
。所以在结束后你仍然有物体是可以的。但奇怪的是,在。。。但无论如何
最后关闭
块是一个有效的过程,但这是一个老派的过程。Java7引入了一个很棒的新特性,名为trytwithresource
,它负责关闭,即使是在出现错误的情况下。然后代码看起来像
try(Connection con = dataSource.getConnection();
CallableStatement callable = con.prepareCall(procedureCall)) {
callableStatement.setString(1, userName);
callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
//Call Stored Procedure
callableStatement.executeUpdate();
// get cursor and cast it to ResultSet
try(ResultSet resultSet = (ResultSet) callableStatement.getObject(2)) {
logger.debug("reslt" + resultSet.getFetchSize());
// loop it like normal
while (resultSet.next()) {
personDTO.setPersonID(resultSet.getString(1));
personDTO.setFirstName(resultSet.getString(2));
personDTO.setLastName(resultSet.getString(3));
personDTO.setFullName(resultSet.getString(4));
personDTO.setEmail(resultSet.getString(5));
}
} //Don't need another catch
} catch(SQLException e) {
e.printStackTrace();
}
不太清楚你说的不关门是什么意思,在变量上使用
close
不会自动将其设置为null
..?在我的数据库连接池中,每个事务都会创建新实例。这是因为Resultset和Callable语句没有关闭吗?我需要将该问题的明确答案留给对JDBC有更多经验的人,但是,只要在调用close
时没有看到异常,就应该使用您显示的代码将其清理干净。谢谢Joachim Lsaksonar您是否反复调用此代码,并且连接不足?是什么让你决定他们不会被释放回游泳池?不太确定你说的他们不会关闭是什么意思,在变量上使用close
不会自动将其设置为null
..?在我的数据库连接池中,每个事务都会创建新实例。这是因为Resultset和Callable语句没有关闭吗?我需要将该问题的明确答案留给对JDBC有更多经验的人,但是,只要在调用close
时没有看到异常,就应该使用您显示的代码将其清理干净。谢谢Joachim Lsaksonar您是否反复调用此代码,并且连接不足?是什么使您确定它们不会释放回池?当然,Jan..会尝试。谢谢。连接后,请关闭用户存在的数据库连接池。它没有删除。这导致maxconnection错误。我的数据库连接轮询maxactive为4。因此,为什么不删除它。如果知道,请给我一个解决方案关闭a来自池的连接将返回到该池。您是否检查了所有从游泳池借用连接的地方?大多数池都有未返回连接的日志记录。我在顶部添加了配置。Iam使用tomcat server.xml设置连接池,使用应用程序上下文设置jndi数据源,并且每个类都调用了数据源。@Jan,您是对的,JDK 1.7支持的自动关闭功能会自动关闭所有资源。应该尽可能地使用它。尝试将MaxWait从5000减少到一个较小的值,然后查看是否释放连接。另外,尝试设置一些超时属性来清理连接。此外,您还可以使用通用连接池(UCP),它是一个Java连接池。请参阅“UCP with tomcat”(www.oracle.com/technetwork/database/application development/planned-unplanned-rlb-UCP-tomcat-2265175.pdf)有关其在Tomcat中配置的更多详细信息,请参阅白皮书。当然,Jan..将尝试。谢谢。连接后,请关闭用户存在的数据库连接池。它没有删除。这导致了maxconnection错误。我的数据库连接轮询maxactive为4。因此,为什么它没有删除。如果知道,请给我一个解决方案关闭池中的连接我会把它放回那个游泳池。您是否检查了所有从游泳池借用连接的地方?大多数池都有未返回连接的日志记录。我在顶部添加了配置。Iam使用tomcat server.xml设置连接池,使用应用程序上下文设置jndi数据源,并且每个类都调用了数据源。@Jan,您是对的,JDK 1.7支持的自动关闭功能会自动关闭所有资源。应该尽可能地使用它。尝试将MaxWait从5000减少到一个较小的值,然后查看是否释放连接。另外,尝试设置一些超时属性来清理连接。此外,您还可以使用通用连接池(UCP),它是一个Java连接池。请参阅“UCP withTomcat”(www.oracle.com/technetwork/database/application development/planned-unplanned-rlb-UCP-tomcat-2265175.pdf)白皮书,了解其在tomcat中配置的更多详细信息。