データベーススペシャリスト 2013年 午前2 問10
問題文

選択肢
ア:
イ:(正解)
ウ:
エ:
🔒 解説は解答すると表示されます
待ちグラフのノード割当【午前2解説】
正解の理由
待ちグラフのノード a は、待ち辺 a → d が示す「a が d の保持するロックの解放を待っている」ことに対応します。スケジュールを時刻順に見ると、T₂ は時刻 t7 に select(C)(共有ロック)を取り、t8 の update(C)(排他ロック取得を試みる)で排他化のために共有ロックを保持している T₁ の解放を待つ挙動をします。すなわち a が待っている相手 d は T₁、したがって a は T₂ に対応します。よって a に該当するトランザクションは イ(T₂)です。
解法ステップ
- 待ちグラフの矢印の意味を確認する。矢印 T_i → T_j は「T_i が T_j のロック解放を待っている」ことを表す。
- スケジュールのロック取得・更新の時刻を順に確認する。特に排他ロック(update)を試みたときに既存のロックによって待ちが発生する箇所を探す。
- 各有向辺とスケジュールの対応を照合する。
- グラフの c → d:c が d を待つ。スケジュールで T₃ は t3 に select(A)、t9 に update(A) を試みる。T₁ は t1 に select(A) を取り、t10 の commit まで保持するため、T₃(update(A))は T₁ を待つ。よって c = T₃、d = T₁。
- グラフの b → a:b が a を待つ。スケジュールで T₄ は t4 に select(B)、t5 に update(B) を試みる。T₂ は t2 に select(B) を取り t2 以降保持しているため、T₄ の update(B) は T₂ を待つ。よって b = T₄、a = T₂。
- グラフの a → d:a が d を待つ。上で a = T₂、d = T₁ となる挙動は、T₂ が t7 に select(C)(共有)を取り t8 に update(C) を試みるが、T₁ が t6 に select(C) を取り t10 まで保持しているため、T₂ が T₁ を待つことと一致する。
- 以上よりノード割当は a=T₂, b=T₄, c=T₃, d=T₁ となる。
選択肢別の誤答解説
- ア: T₁
T₁ は t1, t6 に select を取得し、t10 に commit するまでロックを保持している側であり、他を待つ(矢印の開始点になる)挙動はスケジュール上ほとんど見られない。グラフで a は誰かを待っている(a → d)ので T₁ を a に当てると一致しない。 - イ: T₂
先述の通り、T₂ は C の update を試みる際に T₁ の共有ロックを待つ(a → d)ほか、B では他に共有ロックを与えており、グラフの構造と完全に整合するため正しい。 - ウ: T₃
T₃ は A の update(t9)で T₁ の共有ロックを待つ挙動(c → d)を示すため c に対応する。a(待つ側で B/C に関与)には合致しない。 - エ: T₄
T₄ は B の update(t5)で T₂ の共有ロックを待つ挙動(b → a)を示すため b に対応する。したがって a にはならない。
よくある誤解
- 矢印の向きを逆に解釈する:矢印を「ロックを持っている側が待たれている」と読み違えるとノード割当を逆にしてしまう。矢印は「待っている側 → 待たれている側」。
- 共有ロック同士も待つと考える:共有ロック(select)は基本的に互いに競合しないため、共有取得同士では待たない。待ちが生じるのは通常排他(update)を取得しようとしたとき。
- コミットでしかアンロックされない点を忘れる:合致する待ちが生じるのは、ロックを保持している側がまだ commit していない場合に限られる。
補足コラム
待ちグラフ(wait-for graph)はデッドロック検出に有効です。グラフ上にサイクルが存在すればデッドロックが発生している可能性が高く、いずれかのトランザクションを中止(rollback)してサイクルを解消する対処が必要になります。本問題では有向辺は b→a, a→d, c→d とサイクルを作っておらず、デッドロックには至っていません。スケジュール解析では「いつどのロックを取得/解放するか」を正確に追うことが鍵です。
FAQ
Q. 共有ロックを取った後に update をする場合、なぜ待ちが発生するのですか?
A. 共有ロックから排他ロックへ「アップグレード」する際、排他ロックは他の共有ロックを排除する必要があるため、他のトランザクションが同じ資源の共有ロックを保持していると待ちが発生します。
A. 共有ロックから排他ロックへ「アップグレード」する際、排他ロックは他の共有ロックを排除する必要があるため、他のトランザクションが同じ資源の共有ロックを保持していると待ちが発生します。
Q. なぜ T₃ の update(A) は T₁ を待つのですか?
A. T₁ が t1 に select(A) を取り、t10 まで保持しているため(commit で解放する仕様)、T₃ の t9 update(A) は排他取得のために T₁ の共有ロック解放を待つ必要があるからです。
A. T₁ が t1 に select(A) を取り、t10 まで保持しているため(commit で解放する仕様)、T₃ の t9 update(A) は排他取得のために T₁ の共有ロック解放を待つ必要があるからです。
関連キーワード: ロック, 待ちグラフ, 共有ロック, 排他ロック, デッドロック, スケジュール解析

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

