コンセプト ガイドのデータの同時実行性と一貫性に関するセクションを読むことをお勧めします。
特定の質問への回答:
カーソルが開かれると、結果のローカル コピーがメモリ上に作成されますか?
いいえ、ただし、Oracle の「Multiversion Read Consistency」(上記のリンクを参照) により、カーソルによってフェッチされた行はすべて、カーソルが開かれた時点と一貫性が保たれます。つまり、フェッチされた各行は、カーソルが開かれ、まだ同じ値を保持しています (その間に別のセッションが更新または削除した可能性があります)。
いいえ: データ全体が他のプロセスにロックされていますか?
いいえ
NO : 現在カーソルで使用しているデータが別のプロセスによって変更された場合、または新しい行が追加された場合、カーソルは更新されますか?
カーソルはこれらの変更を認識せず、カーソルが開かれたときに存在していた行を引き続き処理します。
コンセプト ガイドではこれについて詳しく説明していますが、その仕組みの本質は次のとおりです。
- Oracle は、システム変更番号 (SCN)と呼ばれる、継続的にインクリメントされるものを維持しています。
- カーソルが開くと、SCN の現在の値が表示されます。
- カーソルが行をフェッチすると、行にスタンプされた SCN が調べられます。この SCN がカーソルの開始 SCN と同じかそれより低い場合、データは最新であり、使用されます。ただし、行の SCN がカーソルの SCN よりも高い場合は、別のセッションが行を変更した (そして変更をコミットした) ことを意味します。この場合、Oracle はロールバック セグメントで古いバージョンの行を探し、代わりにそれを使用します。クエリが長時間実行される場合、古いバージョンがロールバック セグメントで上書きされた可能性があります。この場合、クエリは ORA-01555 エラーで失敗します。
必要に応じて、このデフォルトの動作を変更できます。たとえば、カーソルの実行中にクエリしている行を他のセッションが変更しないことが重要な場合は、FOR UPDATE
句を使用して行をロックできます。
CURSOR c IS SELECT sal FROM emp FOR UPDATE OF sal;
実行中にクエリで使用される行を変更しようとするセッションは、クエリがコミットまたはロールバックを完了するまでブロックされます。