我有以下代码:
Statement statement =createStatement();
try (java.sql.ResultSet resultset = statement.executeQuery()) {
while (resultset.next()) {
myObject.setProcessingDate(resultset.getDate(1));
myObject.set...
}
}finally {
if (statement != null) {
statement.close();
}
}
我知道语句对象应该在 try-with-resource 块中创建,但这是生成的代码。
随机地,我遇到以下异常:
caused by: java.sql.SQLException: Streaming result set com.mysql.cj.protocol.a.result.ResultsetRowsStreaming@9h6d41205 is still active. No statements may be issued when any streaming result sets are open and in use on a given connection.
Ensure that you have called .close() on any active streaming result sets before attempting more queries.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ServerPreparedStatement.realClose(ServerPreparedStatement.java:549)
at com.mysql.cj.jdbc.ServerPreparedStatement.close(ServerPreparedStatement.java:284)
at com.zaxxer.hikari.pool.ProxyStatement.close(ProxyStatement.java:76)
at mypackage.NamedParameterStatement.close(NamedParameterStatement.java:520)
我已经用谷歌搜索过,但没有找到解释为什么我在关闭声明时会遇到此崩溃。 我的结果集对象的“自动”关闭应该在进入finally块之前以及调用statement.close之前调用。 即使我的 resultset.close 没有被调用,我希望 statements.close() 也会检查结果集是否打开并在需要时关闭它。
我是否遗漏了什么或者为什么会出现这个问题?
try-with-resources 语句是声明一个或多个资源的 try 语句。资源是一个对象,程序使用完毕后必须将其关闭
其实已经自动关闭了,不需要手动调用close方法。
回到你的问题!
注意您提供的错误信息
由以下原因引起:java.sql.SQLException:流式处理结果集 com.mysql.cj.protocol.a.result.ResultsetRowsStreaming@9h6d41205 仍处于活动状态。当任何流结果集在给定连接上打开并使用时,不得发出任何语句。
流模式有一个限制:当在 MySQL 连接上以流模式打开结果集时,您无法使用同一数据库连接来运行其他查询。
也就是说,当你执行这条语句时,很可能已经有其他结果集处于open阶段了。
我已经用谷歌搜索过,但没有找到解释为什么我在关闭声明时会遇到此崩溃。
我不确定你是不是。不是在结束声明时。
结果集对象的“自动”关闭应该在进入finally块之前以及调用statement.close之前调用。
确实如此。
即使我的 resultset.close 没有被调用,我希望 statements.close() 也会检查结果集是否打开并在需要时关闭它。
规格说明
Statement.close()
有这种效果,是的。
再次阅读异常消息,尤其是突出显示的部分:
该消息看起来不像是要结束声明。根据您自己的分析,关闭由该代码片段的同一执行创建的流式传输结果集 com.mysql.cj.protocol.a.result.ResultsetRowsStreaming@9h6d41205 仍然处于活动状态。 当任何流结果集在给定连接上打开并使用时,不得发出任何语句。
Statement
和
ResultSet
之间不应该存在冲突。我倾向于认为您有一个
different ResultSet
与属于同一个
Statement
的 differentConnection
相关联,并且仍然处于活动状态,并且当您尝试创建或执行new
Statement
,而不是当您尝试关闭语句时(尽管毕竟如果从
close()
抛出异常,分析不会受到太大影响)。此类问题的根源包括
ResultSet
;
Connection
;或
因此,明确关闭
Statement
是一种很好的做法。确实如此,这里必须补充一下,如果执行隐式闭包,即如果使用
try-with-resources,那么执行close()
时出现的异常应该单独捕获。
AutoClosable
接口不会自动关闭
Statement
,而是用来隐式关闭它,如上面提到的情况。 现在
//todo,如果无法关闭语句,那么该怎么办?
嗯,这里的原因可能有所不同,但在大多数情况下这没有什么意义,因此可以简单地忽略异常。