トランザクションACID特性とロック機構・デッドロック回避の設計
トランザクションは複数の操作を1つの確定・取消単位として扱います。同時実行で守るべき業務制約、必要なロック、その保持期間を分けて考えます。ACIDの用語だけを覚えても、複数行にまたがる不変条件を自動的に守れるわけではありません。
ACIDの意味と、アプリケーションの責任
特性 | 意味 | 注意点 |
|---|---|---|
原子性 A | 全部を確定するか、全部を取り消す | 外部メール送信などは通常DBのROLLBACKでは取り消せない |
一貫性 C | 定めた制約を満たす状態間を遷移する | 業務制約をスキーマや処理として実装する必要がある |
独立性 I | 同時実行による干渉を制御する | 選んだ分離レベルと実装によって見え方が異なる |
耐久性 D | 確定した変更を障害後も維持する | 永続化・複製の設定と想定する障害範囲を確認する |
口座AからBへ100を移す場合、Aの減額とBの増額を同一トランザクションにします。残高不足の検査も並行更新を考慮し、残高>=100を条件にした更新や行ロックで、確認後の値が他処理に変更されることを防ぎます。
共有・排他ロックと粒度
単純なS/Xモデルでは、同じ対象の共有ロックS同士は共存できますが、排他ロックXは他のS/Xと共存できません。ただし現実のDBMSには複数のロックモードがあり、MVCCによる通常SELECTが行のSロックを取るとは限りません。対象の行、表、ページ、述語と製品仕様を区別します。
意図ロックは、下位の対象にロックを取る予定・状態を上位で示すためのものです。たとえば行をXロックする処理の表レベルIXは、別行を更新する処理のIXと共存し得ます。IXを「表全体のXロック」と混同しないようにします。粒度を大きくすれば管理量を減らせますが、独立した行への並行処理まで待たせる場合があります。
2相ロックとデッドロック
2相ロックでは、ロックを獲得する成長段階と、解放する縮退段階を分け、一度解放した後に新たなロックを獲得しません。厳密2相ロックは排他ロックを確定・取消まで保持する方式として説明されます。全ロックを終了まで保持する方式とは区別される場合があるため、問題中の定義に従います。
2相ロックは直列化可能な実行を実現するための方式ですが、デッドロックを防ぐわけではありません。T1がAをロックしてBを待ち、T2がBをロックしてAを待つと循環待ちになります。同じ行の共有ロックから排他ロックへ変換する場合にも競合し得ます。
T1がAを、T2がBを先にロックした後、互いの対象を待つ例です。最後の2つの要求は完了せず待機します。
順序の統一、検出、再試行を設計する
複数対象を取得する処理は、口座番号や受注番号の昇順など、すべての処理で同じ順序にします。後から別の対象を追加取得する処理やトリガーも含めて順序を確認します。特定の順序で行ロックを取ることだけで、表ロックやロック変換などを含むすべてのデッドロックが消えるわけではありません。
DBMSが待ちグラフの循環を検出した場合は、通常いずれかの処理を中断してロックを解放します。中断後はトランザクション全体を再実行し、再試行回数や間隔を制御します。外部への二重通知や課金を避けるため、処理の冪等性も考慮します。単なるロック待ちとデッドロックをログで区別することも大切です。
演習1:循環待ちを見つける
条件:T1は口座10を保持し口座20を待つ。T2は口座20を保持し口座10を待つ。
問い:デッドロックとなる根拠を答えよう。
解答例:T1→T2→T1の待ちが循環している。
根拠:どちらも相手が解放するまで進めず、通常の順番待ちとは異なる。
演習2:同じ資源の取得順序
条件:全送金処理が2口座をロックする。送金元・送金先の順で取得すると逆順になることがある。
問い:取得順序の改善を短く書こう。(35字以内)
解答例:口座番号の昇順で排他ロックを取得する。(19字)
根拠:業務上の送金方向に関係なく同じ順序にする。
復習で確かめること
例の数値や業務条件を変えて同じ結論になるか確認してください。用語の定義だけでなく、問題文のどの条件から、どの制約・SQL・対策を選んだのかを自分の言葉で説明できれば、次の過去問に進みます。
出典と仕様を確認する
関連するテーマ
次におすすめの学習
編集・検証について
編集・検証:IT資格ラボ編集部
IPAが公開する試験要綱・シラバス・過去問題と、各技術の公式資料を優先して内容を確認しています。制度変更や誤りを確認した場合は、記事を見直して更新します。
編集方針・情報源・訂正方針を見る