【发布时间】:2021-05-20 07:32:36
【问题描述】:
JDBC API 有以下与ResultSet 相关的注释:
当 Statement 对象时,ResultSet 对象会自动关闭 生成它的对象被关闭、重新执行或用于检索下一个 多个结果的序列。
在 JDBC 4.3 规范中:
13.1.4 关闭语句对象
关闭 Statement 对象将关闭该 Statement 对象生成的任何 ResultSet 实例并使该实例无效。
此时很清楚,关闭一个语句对象,应该关闭ResultSet
Statement的JavaDoc有这样的注释:
Statement 接口中的所有执行方法都会隐式关闭一个 如果存在打开的,则该语句的当前 ResultSet 对象。
现在,问题是Statement.closeOnCompletion() 应该如何表现?
指定当它的所有依赖时该语句将被关闭 结果集已关闭。如果执行语句没有产生 任何结果集,此方法无效。
注意:...但是,对 closeOnCompletion 的调用确实会影响后续的 执行语句,以及当前已打开的语句, 依赖,结果集。
语句应该允许重新执行?还是重新执行应该关闭第二次执行的语句?
以测试为例:
@Test
public void testCloseOnCompletionMultipleExecutionResultSets() throws SQLException {
Statement statement = conn.createStatement();
ResultSet rs1 = statement.executeQuery("SELECT 1");
assertFalse("rs1 should be open", rs1.isClosed());
statement.closeOnCompletion();
// Should the second execution throw an SQLException with "Statement closed"?
// or it should work and the statement be closed until the second rs is closed?
ResultSet rs2 = statement.executeQuery("SELECT 2"); // fail or not?
assertTrue("rs1 should be closed by rs2", rs1.isClosed());
assertFalse("rs2 should be open", rs2.isClosed());
assertFalse("statement should be open", statement.isClosed());
rs2.close(); // Only close the statement here since is the last rs open.
assertTrue("statement should be closed", statement.isClosed());
}
【问题讨论】: