データベース (Oracle) の読み取り一貫性を理解するのに問題があります。
私が銀行のマネージャーであるとします。顧客がロックを取得し (これはわかりません)、更新を行っています。彼がロックを取得した後、私は彼らのアカウント情報を表示し、それに対して何かをしようとしています. しかし、読み取りの一貫性のために、顧客がロックを取得する前に存在していたデータが表示されます。それで、それは私が得ているインプットと、その期間中に私が下そうとする決定に影響しませんか?
データベース (Oracle) の読み取り一貫性を理解するのに問題があります。
私が銀行のマネージャーであるとします。顧客がロックを取得し (これはわかりません)、更新を行っています。彼がロックを取得した後、私は彼らのアカウント情報を表示し、それに対して何かをしようとしています. しかし、読み取りの一貫性のために、顧客がロックを取得する前に存在していたデータが表示されます。それで、それは私が得ているインプットと、その期間中に私が下そうとする決定に影響しませんか?
読み取りの一貫性に関するポイントは次のとおりです。顧客が変更をロールバックしたとします。あるいは、制約違反や何らかのシステム障害が原因で、これらの変更が失敗したとしますか?
顧客が変更を正常にコミットするまで、それらの変更は存在しません。ファントム リードまたはダーティ リードに基づいて行う決定は、説明したシナリオよりも有効ではありません。実際、変更が不完全で一貫性がないため、妥当性は低くなります。具体例: 顧客の変更に預金と引き出しが含まれている場合、顧客が預金を行ったがまだ引き出しを行っていないときにアカウントを確認した場合、あなたの決定はどの程度有効でしょうか?
別の例: 長時間実行されるバッチ プロセスは、組織内のすべての従業員の給与を更新します。従業員の給与に対してクエリを実行した場合、半分の従業員の給与が更新され、残りの半分が以前の給与であるというレポートが本当に必要ですか?
編集
読み取りの一貫性は、UNDO テーブルスペース (古い実装ではロールバック セグメント) の情報を使用して実現されます。セッションが、別のセッションによって変更されている表からデータを読み取る場合、Oracle は、その 2 番目のセッションによって生成された UNDO 情報を取得し、最初のセッションに提示された結果セット内の変更されたデータに置き換えます。
読み取りセッションが実行時間の長いクエリである場合、悪名高いORA-1555: snapshot too old
. これは、読み取り一貫性のあるビューを組み立てるために必要な情報を含む UNDO エクステントが上書きされたことを意味します。
ロックは、読み取りの一貫性とは何の関係もありません。Oracle では、書き込みは読み取りをブロックしません。ロックの目的は、他のプロセスが関心のある行を変更しようとするのを防ぐことです。
ユーザー数が多いシステムでは、ユーザーが長時間ロックを「保持」する可能性があるため、通常、オプティミスティックオフラインロックパターンが使用されます。つまり、UPDATE...WHEREステートメントのバージョンを使用します。
行バージョンとして、日付、バージョンID、またはその他のものを使用できます。また、仮想列ORA_ROWSCNを使用することもできますが、最初にそれを確認する必要があります。
変更または明示的なロック ステートメントによってレコードがロックされると、そのブロックのヘッダーにエントリが作成されます。これを ITL (interested transaction list) と呼びます。そのブロックを読み取りに来ると、セッションはこれを見て、ロールバック セグメントから読み取り一貫性のあるコピーを取得する場所を認識します。