4.1. 同時実行制御(排他制御)

1. 概要

 データベース管理システム(DBMS)において、同時実行制御は非常に重要な機能です。これは、複数のトランザクションが同時にデータベースにアクセスする際に、データの整合性を保ちつつ、効率的な処理を実現するための仕組みです。同時実行制御の主な目的は以下の通りです:

  1. データの整合性の保持
  2. トランザクションの独立性の確保
  3. システムの性能と並行性の最適化  この機能がないと、データの不整合や「更新喪失」「ダーティリード」「反復不能読取り」などの問題が発生する可能性があります。本記事では、同時実行制御の主な手法とその具体的な応用例について解説します。

2. 詳細説明

2.1. ロック方式

 ロック方式は、同時実行制御の最も一般的な手法の一つです。これは、トランザクションがデータにアクセスする際に、そのデータに「ロック」をかけることで、他のトランザクションからのアクセスを制御する方法です。

2.1.1. ロックの種類

  1. 専有ロック(排他ロック): データの読み書きを行う際に使用されます。他のトランザクションは、そのデータに対して読み取りも書き込みもできません。
  2. 共有ロック: データの読み取りのみを行う際に使用されます。他のトランザクションも同時に共有ロックを取得できますが、専有ロックは取得できません。

2.1.2. ロック粒度

 ロック粒度とは、ロックをかける対象の大きさを指します。一般的なロック粒度には以下があります:

  • データベース全体
  • テーブル
  • ページ
  • 行(レコード)
  • フィールド  粒度が細かいほど並行性は高くなりますが、ロック管理のオーバーヘッドが増加します。

2.1.3. デッドロックとその回避

 デッドロックとは、複数のトランザクションが互いに相手が保持しているロックの解放を待っている状態です。これを防ぐために、DBMSはデッドロック検出機能を持ち、検出された場合は一方のトランザクションを強制的に中断させます。デッドロックの回避策として、タイムアウトを設定する方法や、資源の獲得順序を管理する方法があります。

2.2. セマフォ方式

 セマフォ方式は、共有リソースへのアクセスを制御するためのカウンタを使用する同期機構です。データベースの文脈では、特定のリソースに同時にアクセスできるトランザクションの数を制御するために使用されます。セマフォ方式は、複数のリソースに対する並行処理が必要な場合に有効です。

2.3. コミット制御

2.3.1. 1相コミットメント

 単一のデータベースシステム内でのトランザクション処理に使用されます。トランザクションの完了時に、すべての更新を一度にコミットします。

2.3.2. 2相コミットメント

 分散データベースシステムで使用される方式で、以下の2つのフェーズから構成されます:

  1. 準備フェーズ:すべての参加ノードにコミットの準備ができているか確認します。
  2. コミットフェーズ:すべてのノードが準備完了であれば、実際にコミットを実行します。  もし準備フェーズで一部のノードが「準備完了」を返さなかった場合、コーディネータは全てのノードに「アボート(中止)」命令を送信し、トランザクション全体をロールバックします。

2.4. 多版同時実行制御(MVCC:MultiVersion Concurrency Control)

 MVCC(多版同時実行制御)は、データの複数のバージョンを保持することで、読み取りトランザクションをブロックせずに書き込みを可能にする手法です。これにより、高い並行性を実現しつつ、データの一貫性を保つことができます。
 MVCCの欠点としては、データの冗長性が増加し、ストレージの使用量が増えることや、実装の複雑さが増す点があります。

参考:PostgreSQL 7.2.3 ユーザガイドより

MVCC(多版型同時実行制御)

3. 応用例

  1. オンラインショッピングサイト:多数のユーザーが同時に商品を注文する際、在庫数の整合性を保つために同時実行制御が使用されます。例えば、複数のユーザーが同時に同じ商品をカートに入れる場合、在庫の更新が競合しないようにする必要があります。
  2. 銀行システム:複数の取引が同時に行われる中で、口座残高の正確性を保証するために使用されます。特に、同一口座に対する複数の入出金が同時に処理される場合に重要です。
  3. 航空券予約システム:多数のユーザーが同時に座席を予約する際、二重予約を防ぐために利用されます。たとえば、最後の一席を複数のユーザーが同時に予約しようとするケースで役立ちます。
  4. SNSプラットフォーム:大量のユーザーが同時にコンテンツを投稿・編集する際のデータ整合性の維持に使用されます。例えば、コメントや投稿の同時編集を管理するために同時実行制御が用いられます。

4. 例題

例題1

Q: あるデータベースシステムで、トランザクションAがテーブルXの行1に対して専有ロックを取得しています。この状態で、トランザクションBが同じ行に対して共有ロックを要求した場合、どうなりますか?

A: トランザクションBの共有ロック要求は拒否されます。専有ロックは他のトランザクションからのアクセスを完全に排除するため、共有ロックであっても取得することはできません。トランザクションBは、トランザクションAが専有ロックを解放するまで待機する必要があります。

例題2

Q: 2相コミットメントのプロトコルにおいて、準備フェーズで一部のノードが「準備完了」を返さなかった場合、コーディネータはどのような動作を行いますか?

A: コーディネータは全てのノードに対して「アボート(中止)」命令を送信します。これにより、トランザクション全体が取り消され、各ノードで行われた部分的な更新はロールバックされます。2相コミットメントでは、全てのノードが準備完了でない限り、コミットフェーズに進むことはできません。

例題3

Q: MVCCを採用しているデータベースシステムの利点を2つ挙げてください。

A: MVCCの主な利点は以下の通りです:

  1. 読み取りトランザクションが書き込みトランザクションをブロックしない(またその逆も)ため、高い並行性が実現できます。
  2. 長時間実行されるトランザクションがある場合でも、短時間のトランザクションの処理が妨げられにくくなります。これにより、システム全体のスループットが向上します。

5. まとめ

 同時実行制御は、複数のトランザクションが同時にデータベースにアクセスする際に、データの整合性を保ちつつ効率的な処理を実現するための重要な機能です。主な手法として、ロック方式、セマフォ方式、コミット制御、多版同時実行制御(MVCC)があります。

 これらの技術を適切に使用することで、データベースシステムは以下を実現します:

  1. データの整合性の維持
  2. トランザクションの独立性の確保
  3. システムの並行性と性能の最適化