web-dev-qa-db-ja.com

DB2 for z / OSで失われた更新の回避

DB2 DBMS for z/OSでの「コミットされていない読み取り」分離レベルについて質問があります。

記事上で

https://www.ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/perf/src/tpc/db2z_isolationissues.html

iBMナレッジ・センターでは、反復可能読み取り以外の分離レベルを使用すると、次の現象が発生する可能性があると述べられています。

  • ファントムロー
  • ダーティリード
  • 繰り返し不可の読み取り

また、ANSI-SQL 92標準では、この3つの現象のみが可能な限り定義されており、更新が失われることはないとされています。

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

(68ページの4.28章「SQLトランザクション」を参照)。

見積もり:

「4つの分離レベルは、各SQLトランザクションが完全に実行されるか、まったく実行されないこと、および更新が失われないことを保証します。」

これまでのところ、プログラム内のSQLステートメントが「WITHUR」節でコーディングされている場合に、DB2(for z/OS)が更新の損失を防ぐ方法についての明確な答えは見つかりませんでした。

「LostUpdate」現象の典型的な例を想定してみましょう。

  1. トランザクションT1は、テーブル「R」から値「X」をメモリに読み込み、1ずつインクリメントします。
  2. トランザクションT2は、テーブル「R」から値「X」をメモリに読み込み、2ずつインクリメントします。
  3. トランザクションT1はその変更をコミットします
  4. トランザクションT2は変更をコミットします。値X + 2はデータベースに格納されますが、T1とT2がシリアル化されている場合、X +3が正しい結果になります。

トランザクションが「更新用」カーソルによってデータを読み取らないと仮定します。これにより、DB2の「カーソル安定性あり」の分離レベルが内部的に発生します。

私の理解では、この異常を防ぐために、トランザクションT1は、T1がコミットしない前に、T2が同じ値を読み取らないように、修飾行に排他ロックを設定する必要があります。

それにもかかわらず、上記のリソースの時点では、それにもかかわらずLost Updateの異常は発生しませんが、これはどのように行われますか?

1
Monty Burns

DB2の観点から見たLost Update現象は、このトランザクションがまだ終了していない場合に、トランザクションの更新を上書きする機能です。
DB2では不可能です。このようなトランザクションは、このトランザクションが終了するまで対応する行を排他的にロックし、他のトランザクションはこの行を上書きできないためです。このような行ロックは、トランザクションの終了後にのみ削除されます。
しかし、あなたはLost Update現象の別の説明を提供しました。 DB2自体は、アプリケーションがそのような「失われた更新」を行うのを防ぐことはできません。
このような状況になりたくない場合は、トランザクションを適切に設計する必要があります。 DB2は、これをさまざまな手法で実行する機能を提供します。

0
Mark Barinstein