ITパスポート 2013年 秋期 問67
問題文
あるトランザクション処理は、①共有領域から値を読み取り、②読み取った値に数値を加算し、③結果を共有領域に書き込む手順からなっている。複数のトランザクションを並列に矛盾なく処理するためには、トランザクション処理のどの時点で共有領域をロックし、どの時点でロックを解除するのが適切か。


選択肢
ア:
イ:(正解)
ウ:
エ:
🔒 解説は解答すると表示されます
共有領域のロックと解除の時点の判断【ITパスポート 解説】
正解の理由
この問題では、トランザクション(複数の操作を一つのまとまりで扱う処理)の「読み取り→計算→書き込み」という一連の手順を、他のトランザクションと矛盾なく並行実行する必要があります。ここで必要なのは「読み取った値を基に計算し、その結果を正しく書き戻す」一連の処理が他から干渉されないことです。
ロック(他の処理が同じデータを同時に変更できないようにする仕組み)を時点(a)でかけ、時点(d)で解除する選択肢、すなわち表中の イ が正しいです。理由は次の通りです。
- 読み取り(①)より前の時点(a)でロックをかければ、同時に別のトランザクションがその共有領域を変更することを防げます。
- 書き込み(③)を終えるまでロックを保持すれば、読んだ値に基づく計算結果を書き戻す際に別の更新で値が上書きされる(競合による矛盾)ことを防げます。
- 書き込み(③)後にロックを解除する(時点(d))ことで、更新が確定するまでの全操作を原子(途中で別処理に割り込まれない)にできます。
この「ロック=時点(a)、解除=時点(d)」が、読み取り→更新→書き戻しのまとまり(クリティカルセクション)を守る最小かつ正しい方法です。
解法ステップ
- 問題の処理手順を確認する:①共有領域から読み取り → ②加算(計算) → ③共有領域に書き込み。
- 「他のトランザクションの介入で不整合が起きる箇所(クリティカルセクション)」を見つける。ここでは①〜③の全体が該当。
- クリティカルセクションの開始前にロックをかけ、終了後に解除するのが基本。よってロックは時点(a)、解除は時点(d)。
- 表の選択肢と照らし合わせて、該当するものを選ぶ(イ)。
例として擬似コード:
# 悲観的ロックのイメージ(python風の擬似)
lock.acquire() # 時点(a):ロック
value = shared.read() # ① 共有領域から読み取り
value = value + N # ② 加算(計算)
shared.write(value) # ③ 書き込み
lock.release() # 時点(d):ロック解除
選択肢別の誤答解説
-
ア(ロック:時点(a)、解除:時点(c))
→ 読み取り後の計算(②)と書き込み(③)の間でロックを解除してしまうので、書き込み(③)の際に他のトランザクションが介入して値を書き換える可能性があり、「読み値に基づく更新」が壊れます(失われた更新や不整合が発生)。 -
ウ(ロック:時点(b)、解除:時点(c))
→ ロックを時点(b)でかけると、読み取り(①)時点ではロックされていません。したがって読み取りと書き込みの間に別処理が入り込み、読み取った値自体が古くなったり、他が同じ値を基に更新してしまう競合が起きます。 -
エ(ロック:時点(b)、解除:時点(d))
→ 読み取り(①)をロック無しで行うため、①の「読み」が他の更新と競合し得ます。時点(b)から時点(d)までは保護されますが、初期読み取り段階で既に矛盾が起きる可能性があるため不十分です。
よくある誤解
-
「書き込みだけロックすればよい」
→ 書き込みだけ保護すると、読み取り時点の古い値を基に計算して上書きしてしまう「失われた更新(lost update)」が起きます。読み取り→計算→書き込みを一つのまとまりとして保護する必要があります。 -
「ロックはできるだけ短くすべき」=すぐ解除すれば良い
→ 確かにロックは短いほど待ちが少なく効率的ですが、必要な処理(ここでは書き込み)が終わる前に解除すると整合性が壊れます。正しくは「必要最小の範囲で、かつ整合性を保てる期間だけ」ロックすることです。
補足コラム
-
悲観的ロックと楽観的ロック:今回の考え方は「悲観的ロック(pessimistic locking:競合を前提にロックして安全にする方式)」です。代わりに「楽観的ロック(optimistic locking:まず処理を進め、書き込み時に衝突がなければ確定、衝突があれば再試行)」という手法もあります。楽観的は待ちが少ない場面で有効ですが、衝突時の再試行処理が必要です。
-
データベースのトランザクション分離レベル:RDBMS(関係データベース)には、並行実行の問題(ダーティリード、不可重読、ファントムなど)を扱うための「分離レベル」があります。今回のケースは「不可重読」や「更新の競合」に関係します。実務ではロック方式か分離レベルで整合性を確保します。
FAQ
Q. ロックをかけると処理が遅くなりませんか?
A. はい。ロック中は他が待つため遅くなります。重要なのは「整合性」と「性能」のバランスです。必要最小限の範囲でロックする、または楽観的な方法を使うなどで調整します。
A. はい。ロック中は他が待つため遅くなります。重要なのは「整合性」と「性能」のバランスです。必要最小限の範囲でロックする、または楽観的な方法を使うなどで調整します。
Q. 読み取りだけの操作でもロックは必要ですか?
A. 読み取りのみで値を変更しない場合は通常ロック不要です(共有読取は許容できる)。ただし「読み取った値を基に後で書き込む」場合は読み取りから書き込みまで保護する必要があります。
A. 読み取りのみで値を変更しない場合は通常ロック不要です(共有読取は許容できる)。ただし「読み取った値を基に後で書き込む」場合は読み取りから書き込みまで保護する必要があります。
Q. この問題の考え方はプログラム以外にも使えますか?
A. はい。複数人で同じドキュメントを編集する、在庫管理で同じ商品の引当を行うなど、同期(競合回避)が必要な場面すべてに当てはまります。
A. はい。複数人で同じドキュメントを編集する、在庫管理で同じ商品の引当を行うなど、同期(競合回避)が必要な場面すべてに当てはまります。
関連キーワード: トランザクション、ロック、排他制御、クリティカルセクション、競合、失われた更新、悲観的ロック、楽観的ロック、原子性 (atomicity)

\ せっかくなら /
ITパスポートを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

