排他制御

この記事での学習内容 ITパスポート 基本情報 応用情報

データの整合性を保つために,複数のトランザクションが同時にデータベースのデータを更新することが起こらないようにする排他制御の考え方を理解する。また,ロック方式,セマフォ方式,コミット制御の仕組みを理解する。

用語例:専有ロック,共有ロック,ロック粒度,デッドロック,1 相コミットメント,2相コミットメント

排他制御

DBMSはデータの矛盾を防止するため、排他制御によるアクセスタイミングのコントロールを行います。一つのファイルに対して、一つのトランザクション(取引単位)による更新処理中に、別のトランザクションが更新を行うことを禁止し、先の更新処理が完了しなければ、次の更新処理ができないようにします。

占有ロック

占有ロックとは、一つのファイルへのアクセスを一つのトランザクションだけに専有させて、他のトランザクションのアクセスを禁止することです。つまり、データの更新に対しても、参照に対してもロックを掛けます。先に占有ロックがかかっていた場合、後から占有ロックを掛けることができません。

共有ロック

共有ロックは、一つのファイルへのアクセスを複数のトランザクションに許可して、占有ロックを禁止することです。共有ロックは、共通の参照ファイルなどに用います。

先に占有ロックがかかっていた場合、後から共有ロックはかけることができませんが、先に共有ロックがかかっていた場合、後から共有ロックをかけることはできます。

ロック粒度

ロック粒度とは、ロックで保護するデータの細かさの度合いです。

粒度が粗いということは、保護するデータの単位が大きいということです。ロックのオーバーヘッドは減るという特徴がある一方で、アクセスを禁止される確率が高くなり、アクセス可能になるまで待つことから、性能が低下しがちです。

粒度が細かいということは、保護するデータの単位が小さいということです。アクセスを禁止される確率が低いので、性能が高いのが特徴ですが、ロックのための処理の回数が増えてオーバーヘッドが増えます。

デッドロック

デッドロックとは、複数のプロセスが相手が専有している資源の解放を待って、どちらの処理も停止してしまうことです。

対処法としては、以下の方法があります。

  • 更新プロセスの開始時に、表単位でロックをかける。
  • 更新プロセス開始時に、更新対象の全レコードにロックをかける。
  • 全てのプロセスで、更新処理を行う順序を合わせる。

コミットメント

あらゆる事態に対応するために、DBの更新は”仮”の状態で行われ、いつでももとに戻せるようにしておくのが一般的です。
*元に戻すことをロールバックという。

また、仮の更新結果は他のトランザクションからは見えません。

コミットメント(コミット)は、仮の更新を確定させる処理のことを指します。コミットが完了してはじめて、他のトランザクションからも更新後の値が参照できるようになります。

1相コミットメント

1相コミットメントとは、1回の処理でデータベースの更新が確定(コミット)する方式です。単相コミットメントとも呼ばれます。

単一のデータベースだけで運用されている場合に利用されたりしますが、データベースが複数関係し分散された環境で運用される場合、1相コミットメント方式では、データベース間に矛盾が生じるリスクがあるため、後述の2相コミットメント方式が採用されています。

2相コミットメント

2相コミットメント方式では、データベースの更新を「更新準備」と「更新」の2回のフェーズに分けて処理します。この方式は、ネットワークなどを利用し、分散されたデータベースが複数ある場合、1相コミットメント方式では複数のデータベースの更新が正常に終了できない場合があります。

確実に全てのデータベースの更新を行うには、分散されたデータベースの更新準備が全て整ってから更新を行えば、すべてのデータベースの更新が行えることになります。このように、更新準備フェーズと更新フェーズの2相にする方式を、2相コミットメントと呼んでいます。

もし、更新準備は終わり、更新フェーズに入ってから何らかの障害にて更新が行えなかった場合は、ロールバック処理を全てのデータベースに対して行うことで、更新前の状態にデータベースを戻すことができます。