简体   繁体   English

为什么我打开的 ResultSet 在更改 session 后会自动关闭

[英]Why does my open ResultSet automatically close after alter session

We have code that opens a ResultSet against a view in the Oracle root container, cdb$root .我们有针对 Oracle 根容器 cdb cdb$root中的视图打开ResultSet的代码。 While the code iterates the rows, there is a use case where we need to perform a specific function call but this call must be made within the context of a specific plugable database, in our case ORCLDPB1 .当代码迭代行时,有一个用例我们需要执行特定的 function 调用,但此调用必须在特定可插入数据库的上下文中进行,在我们的例子中ORCLDPB1 Effectively the code looks like the following:实际上,代码如下所示:

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());
      }
    }     
  }
}

The output is: output 是:

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

Then when the while checks resultSet.next() on the second iteration this yields然后当 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)

Through debugging, I've determined that the outer ResultSet remains open until the ALTER SESSION is executed and immediately afterward making call to isClosed() returns that the outer result-set is no longer open.通过调试,我确定外部ResultSet保持打开状态,直到ALTER SESSION被执行,然后立即调用isClosed()返回外部结果集不再打开。

Is this behavior due to performing another operation while an existing ResultSet is open or is this because of the actual statement being executed, namely ALTER SESSION ?这种行为是由于在现有ResultSet打开时执行另一个操作,还是因为正在执行的实际语句,即ALTER SESSION If the latter, why does this force a ResultSet to be invalidated?如果是后者,为什么这会强制ResultSet无效?

From the Oracle "Administering a CDB with SQL*Plus" documentation :来自Oracle“使用 SQL*Plus 管理 CDB”文档

40.2.3 Switching to a Container Using the ALTER SESSION Statement 40.2.3 使用 ALTER SESSION 语句切换到容器

... ...

The following are considerations for using the ALTER SESSION SET CONTAINER statement:以下是使用ALTER SESSION SET CONTAINER语句的注意事项:

  • ... ...
  • If you open a cursor and use ALTER SESSION SET CONTAINER to switch to different container, then you cannot fetch data from that cursor until you switch back to the container in which the cursor was opened. If you open a cursor and use ALTER SESSION SET CONTAINER to switch to different container, then you cannot fetch data from that cursor until you switch back to the container in which the cursor was opened.

First of all I've checked simple scenario in SQL*Plus - it works fine:首先,我检查了 SQL*Plus 中的简单场景 - 它工作正常:

SQL> alter session set container=pdb1;

Session altered.

SQL> create table test as select 1 a from dual;

Table created.

SQL> var c refcursor;
SQL> exec open :c for select * from test;

PL/SQL procedure successfully completed.

SQL> alter session set container=cdb$root;

Session altered.

SQL> alter session set container=pdb1;

Session altered.

SQL> print c

         A
----------
         1

As you can see I opened cursor in PDB1, switched to CDB$ROOT, then returned to PDB1 and successfully fetched from cursor.可以看到我在PDB1中打开cursor,切换到CDB$ROOT,然后返回到PDB1,成功从cursor中获取。

So what exactly are you doing in // perform some PDB specific operation ?那么你到底在做什么// perform some PDB specific operation Are there any transactions?有交易吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM