0

我正在开发一个 C++ 程序,使用 OCI 从 Oracle 数据库中查询一些结果集。我发现即使我用“ update table set col=xxx where xxx”手动更新了行,结果集也会被缓存。OCI 调用仍在获取旧数据。这种缓存是如何发生的?有没有办法禁用它?如何检查缓存是否真的发生?通过检查执行计划?

4

2 回答 2

3

当您在单独的会话(您的 SQL*Plus 会话)中进行更改时,这些更改仅在您进行更改时对您的当前会话(您的 OCI 应用程序)可见commit。在您commit在 SQL*Plus 中执行事务之前,您将继续看到该行的当前版本,而不是您在 SQL*Plus 会话中更改的版本。您的 OCI 应用程序使用默认的事务隔离,READ COMMITTED因此您只能读取已提交的数据。

需要注意的一件事是,如果您从 OCI 应用程序打开游标,则从游标句柄获取的数据是在打开游标时存在的数据。因此,如果您在 OCI 中打开游标,在 SQL*Plus 中提交更改,然后从 OCI 获取数据,您的 OCI 应用程序将看不到在 SQL*Plus 中提交的更改。您必须重新打开游标才能看到新提交的行。

从技术上讲,这不是缓存。相反,这就是 Oracle 的多版本读取一致性的工作方式。假设默认事务隔离级别,每次打开游标时,都会捕获当前的 SCN(系统更改号),并检索到该 SCN 的数据。如果自该 SCN 以来某个块已更改(无论是否已提交),Oracle 会将该更改的 UNDO 向量应用于该块,然后再将其返回到您的会话。

于 2012-08-21T15:30:50.693 回答
1

是的,您需要在 SQL*Plus 或SET AUTOCOMMIT ON.

查看查询计划将清楚地显示您是否正在使用客户端结果缓存,您将RESULT CACHEOperation列中看到。

于 2012-08-21T15:34:28.330 回答