Oracle? DB2? Symfoware? HiRDB? SQL鯖?
商 用 R D B M S 徹 底 比 較 ス レ ッ ド それに、ANSIの定義の話になったところで、
せいぜいfjニュースグループ程度の議論しかでけんでしょ。
そもそもレコード排他は、ACID特性のACIの部分を実現するための技術。
・限定品購入トランザクション:あと2名様って書いてあったから予約しよう
正しい結末:ちゃんと予約できる
・期末テストトランザクション:見直してみたら間違えていたので修正しよう
正しい結末:直した結果が評価されて点がつく
・障害報告トランザクション:お客さんに今日の障害表を報告しよう
正しい結末:今日の障害表が報告される
・今日の晩御飯トランザクション:冷蔵庫にあと何個くらい卵があったか子供に数えさせよう
正しい結末:ざっぱに見てあるかないかがわかる
数多のRDBMSは、これらが正しく行われるために
1SQLごとにロックの付与、質、粒度を変化させて実現を図る。
付与する期間はトランザクションの開始〜終了までの間。
・障害報告トランザクション
これについて、Oracle型の結末と、DB2型の結末は違う場合がありえる。
報告役のアクション:
お客さんに今日の障害表を報告しよう。
障害表で今日まででまだ未解決のものを探して報告するのだ。
障害調査員のアクション:
やっと社内レビューおわったよ。
障害表に原因判明って書いとけって課長が言ってたっけ。急いで直すべ。
↓
Oracle:
「障害表に原因判明って書いとけって課長が言ってたっけ。急いで直すべ。」が
反映されていない傷害報告が行われる可能性がある。
ただし、報告役の人間は、きちんと報告時間にやってくることが保障される。
DB2:今日報告したい内容の障害報告がなされることが保障される。
ただし、報告役の人間が、報告時刻にすこし遅れてやってくる場合がありえる。
Oracle :間に合わなかった報告項目は、割愛
DB2 :正しい報告を行うためにロック待ち
Oracle :間に合わなかった報告項目は、割愛
DB2 :正しい報告を行うためにロック待ち
↓
Oracle:
read committedとは既コミット済みを読ませればよいので、係でコミット済みのものを読ませる
・読もうとした内容が、他トランザクションでコミットが済んでいないものがある
→その前の時点でコミット済みのレコードを読ませる。
(この解釈はOracleだけが行っている解釈)
DB2:
read committedとは、コミットが済んでいないものを読ませてはいけないので、
書き手トランザクションと読み手トランザクションの排他関係でコミット済みのものを読ませる
・読もうとした内容が、他トランザクションでコミットが済んでいないものがある
→他トランザクションの終了を待つ
結論:
read committedの解釈は現状2つにわかれている。
性能をとるなら、Oracle的解釈
正しさをとるなら、DB2的解釈
(正誤表)
(誤)
Oracle:
read committedとは既コミット済みを読ませればよいので、係でコミット済みのものを読ませる
↓
(正)
Oracle:
read committedとは既コミット済みを読ませればよいので、
排他をとらず、読み手には、前に誰かがコミット済みにしたものを読ませる
また、Oracleで
set transaction read write , isolation level read committed
と書かれているトランザクションを正しくDB2で動かすには、
set transaction read write , isolation level read uncommitted
と書かないといけません。
試しに、結合テストでタイミングが気になる処理のテストを実施してみてください。
そうした場合、そうしなかった場合でテスト結果が変わってきます。
Oracleのときのテスト結果と合うのは、後者の
set transaction read write , isolation level read uncommitted
と書いた場合になります。 なんでこんなにくどく書くかというと、
最近、基幹系のアプリ障害でこういうケースがあったからです。
お客さんって、どちらかというと汎用機よりの考えをします。(つまりDB2より)
一方最近のSEはOracleよりの考えで報告します。
仲裁するヤツの立場にもなれっつーのよ、ホント。