0

OCI を使用して Oracle データベースから結果セットを照会する C++ プログラムを開発しています。「 」を使用して行を手動で更新しても、結果セットがキャッシュされていることがわかりましたupdate table set col=xxx where xxx。OCI 呼び出しはまだ古いデータを取得しています。このキャッシングはどのように行われますか? 無効にする方法はありますか?キャッシングが実際に行われるかどうかを確認するにはどうすればよいですか? 実行計画を確認して?

4

2 に答える 2

3

別のセッション(SQL*Plusセッション)で変更を行った場合、それらの変更は、変更時に現在のセッション(OCIアプリケーション)にのみ表示されますcommit。SQL*Plus でトランザクションを実行するまでcommit、SQL*Plus セッションで変更したバージョンではなく、行の現在のバージョンが引き続き表示されます。OCI アプリケーションはデフォルトのトランザクション分離を使用しているREAD COMMITTEDため、コミットされたデータのみを読み取ることができます。

注意すべき点の 1 つは、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 CACHEされOperationます。

于 2012-08-21T15:34:28.330 に答える