java - 为什么我打开的 ResultSet 在更改会话后会自动关闭
问题描述
我们有代码可以ResultSet
在 Oracle 根容器中打开一个视图,cdb$root
. 当代码迭代行时,有一个用例,我们需要执行一个特定的函数调用,但是这个调用必须在一个特定的可插入数据库的上下文中进行,在我们的例子ORCLDPB1
中。实际上,代码如下所示:
while (resultSet.next()) {
LOGGER.info("ResultSet Closed (Top Of Loop): {}", resultSet.isClosed());
if (someSpecialUseCaseIsTrue) {
try (Statement s = connection.createStatement()) {
LOGGER.info("ResultSet Closed (Creating new statement): {}", resultSet.isClosed());
try {
s.executeUpdate("ALTER SESSION SET CONTAINER=ORCLPDB1");
LOGGER.info("ResultSet Closed (after alter session): {}", resultSet.isClosed());
// perform some PDB specific operation
}
finally {
s.executeUpdate("ALTER SESSION SET CONTAINER=cdb$root");
LOGGER.info("ResultSet Closed (after alter back to root): {}", resultSet.isClosed());
}
}
}
}
输出是:
ResultSet Closed (Top Of Loop): false
ResultSet Closed (Creating new statement): false
ResultSet Closed (after alter session): true
ResultSet Closed (after alter back to root): true
然后当 while 检查resultSet.next()
第二次迭代时,这会产生
java.sql.SQLException: Closed Resultset: next
at oracle.jdbc.driver.InsensitiveScrollableResultSet.ensureOpen(InsensitiveScrollableResultSet.java:133)
at oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:428)
通过调试,我确定外部ResultSet
在执行之前保持打开状态,ALTER SESSION
然后立即调用isClosed()
返回外部结果集不再打开。
这种行为是由于在现有文件ResultSet
打开时执行另一个操作,还是因为正在执行的实际语句,即ALTER SESSION
?如果是后者,为什么这会迫使 aResultSet
无效?
解决方案
来自Oracle“使用 SQL*Plus 管理 CDB”文档:
40.2.3 使用 ALTER SESSION 语句切换到容器
...
以下是使用该
ALTER SESSION SET CONTAINER
语句的注意事项:
- ...
- 如果您打开一个游标并使用
ALTER SESSION SET CONTAINER
切换到不同的容器,那么您无法从该游标获取数据,直到您切换回打开游标的容器。
推荐阅读
- codeigniter - 消息:未定义变量:ver
- java - 在注入的类中注入 Dagger2 错误
- javascript - 我将如何使用 javascript 将包含两个城市(及其州)的字符串分隔成它们自己的变量?
- laravel - 为什么我无法成功运行 npm run dev?
- html - 在 Angular 7 中,当嵌套两个按钮时,第二个按钮被忽略
- sql-server - 按财政年度划分的 SSRS/SQL 组 -- SQL Server 2014
- javascript - NodeJs Express 从数组生成获取请求
- javascript - 如何使用 node_modules/ 访问子依赖项的 .bin 脚本
- arrays - 如何将 ESNext Array 函数添加到现有的嵌套数组接口?
- python - 如何为 Celery 任务添加自定义 ID 以便稍后撤销任务?