PR

2相ロッキングプロトコル /2PL とは?3分でわかりやすく解説

Database

2相ロッキングプロトコル(2PL/2相ロック)とは、データベース管理システムの並行制御のための一般的なプロトコルです。

2相ロッキングプロトコル(2PL/2相ロック)
図1:2相ロッキングプロトコル(2PL/2相ロック)

参考 データベース管理システムとは?

このプロトコルに従うトランザクションは、ロックの取得が成長フェーズ縮小フェーズの2つの段階で行われるため、この名前が付けられました。

成長フェーズではロックを取得し、縮小フェーズではロックを解放します。結果として、2PLはデータベースシステムにおける一貫性と整合性を確保する重要な役割を果たします。

このページでは、2相ロッキングプロトコル(2PL)の基本原則から具体的な動作、利点と欠点、実装例までを総合的に解説します。特にシステムエンジニア、データベース管理者、学生など、データベースの並行制御に興味を持つ方々にとって、有益な情報を提供することを目指しています。

このページで学べる内容
  • 2相ロッキングプロトコルの基本
  • 2相ロッキングプロトコルの動作
  • 2相ロッキングプロトコルの利点と欠点

データベースエンジニアを目指す方であれば知らないと恥ずかしい基本知識の1つです。是非最後までご覧ください。

スポンサーリンク

2相ロッキングプロトコル(2PL)とは?

2相ロッキングプロトコル(2PL)は、名前の通り、2つのフェーズで構成されるロッキングプロトコルです。データベースで多くの人が同時に作業するとき、お互いの作業がぶつからないように管理する方法の1つとして使用されます。

2相ロッキングプロトコル(2PL)は、具体的には成長フェーズ縮小フェーズの2つのフェーズから成り立ちます。

2相ロッキングプロトコル(2PL/2相ロック)
図1:2相ロッキングプロトコル(2PL/2相ロック)

PL1 成長フェーズ(Growing Phase)

  • 目的: トランザクションが必要なリソースに対してロックを取得します。
  • 動作: このフェーズでは、トランザクションは新たなロックを取得することができますが、一度解放したロックを再取得することはできません。
  • 注意点: 成長フェーズの終了時点で必要な全てのロックを取得しておく必要があります。

PL2 縮小フェーズ(Shrinking Phase)

  • 目的: トランザクションが完了するために不要なロックを解放します。
  • 動作: このフェーズでは、トランザクションはロックを解放することができますが、新たなロックを取得することはできません。
  • 注意点: 必要なロックを解放してもデータの整合性が保たれるように慎重に解放する必要があります。
なぜ2つのフェーズに分けるのか?

2相ロッキングプロトコルが2つのフェーズに分かれる理由は、データの一貫性と整合性を保つためです。

具体例を通して、この点を詳しく見ていきましょう。

銀行の口座間送金

口座Aから口座Bへの送金を行うトランザクションを考えます。

ステップ1 成長フェーズ

  • ロック取得: 口座Aの残高をチェックし、送金額が足りるか確認するため、口座Aにロックを取得。
  • 新たなロック取得: 送金額が足りることが確認できれば、送金先の口座Bにロックを取得。

この段階では、ロックの取得が柔軟に行えます。

ステップ2 縮小フェーズ

  • ロック解放の開始: 口座Aから送金額を減らし、口座Bに送金額を加算後、ロックを解放。
  • 新しいロック取得の禁止: 一度縮小フェーズに入ると新しいロックの取得はできなくなります。

もし、この操作を2相ロッキングプロトコルに従わないとすると、例えばトランザクション1が口座Aのロックを取得している間に、トランザクション2が口座Bのロックを取得してしまう可能性があります。両者が互いの口座にロックを取得しようとすると、お互いが待ち合いの状態に陥りデッドロックが発生します。

また、同様に送金処理中に他のトランザクションが同じ口座への入金を行うと、最終的な口座残高が正しく反映されない可能性が出てきてしまいます。

2相ロッキングプロトコルは、データベースの一貫性と整合性を確保する重要なプロセス。2つのフェーズに分けない場合、死ロックの発生、データの不整合、パフォーマンスの低下など、多岐にわたる弊害が生じる可能性が生じてしまいます。

2相ロッキングプロトコルのロックの種類

2相ロッキングプロトコルでは、以下のロックが組み合わせて使用され、データベースの一貫性と整合性を確保します。各ロックの種類とその特性を理解することは、効果的なトランザクション処理の設計において重要なので、ここで詳細を以下に記載しておきます。

ロックの種類概要用途特徴
共有ロック(Shared Lock)複数のトランザクションがデータを読むことを許可する読み取り専用の処理他の共有ロックは取得可、排他ロックは取得不可
排他ロック(Exclusive Lock)単一のトランザクションだけがデータにアクセスできる書き込みを伴う処理(更新、削除など)他のいかなる種類のロックも取得不可
意図ロック(Intention Lock)特定のロックを取得する意図を表明する意図の通知デッドロック防止の効率的な手段
互換性のあるロック2つの異なるトランザクションが同時に取得できる同時データアクセス例:共有ロック同士は互換性があるため、同時に取得可
2相ロッキングプロトコルで使用される主要なロックの

2相ロッキングプロトコルのメリット・デメリット

ここからは、2相ロッキングプロトコル(2PL)のメリットとデメリットについて、より具体的に実際のコード例も交えながらご説明していきます。

メリット1:整合性の保証

2PLはデータへのアクセスが他のトランザクションと干渉しないように制御します。これにより、データの整合性、つまり一貫性が保たれます。

以下のコードは、トランザクションを開始する際に、必要なロックを取得するシンプルな例です。

def start_transaction():
    acquire_locks() # データにアクセスする前にロックを取得
    # 以下、処理の実行

参考 Python:def

ロックを取得することで、同時にデータへのアクセスを試みる他のトランザクションと競合しないようにします。

メリット2:並行処理のサポート

2PLは、多くのトランザクションを同時に効率的に処理できます。ロックの管理により、複数のトランザクションが同時にデータにアクセスしても問題が発生しないようにします。

# 複数のトランザクションを並行実行
threads = [Thread(target=transaction_process) for _ in range(10)]
for t in threads:
    t.start()

このコードは、10個のトランザクションを同時に起動しています。それぞれのトランザクションは独立して処理されます。

デメリット1:デッドロックの可能性

デッドロックは、トランザクション同士が互いのロックを待ち合う状態のことです。2PLではこの問題が発生する可能性があります。

# デッドロックの検知と解決
def detect_deadlock():
    # デッドロックの検知ロジック
    # 必要に応じてロックの解放

このコード例は、デッドロックを検知し、必要に応じてロックを解放する仕組みを示しています。

デメリット2:パフォーマンスの低下

2PLでロックの競合が頻繁に発生すると、システムの効率が低下することがあります。つまる、あるトランザクションがロックを持っている間、他のトランザクションが待機する必要があるため、処理の遅延が発生する可能性があります。

from threading import Lock

lock = Lock()

def transaction_process():
    with lock: # このロックが競合すると効率が低下します
        # 複雑な処理
        pass

# 複数のトランザクションを並行実行
threads = [Thread(target=transaction_process) for _ in range(10)]
for t in threads:
    t.start()

このコードは、10個のトランザクションが同一のロックを取得しようとして競合する状況を示しています。一度に1つのトランザクションしかロックを取得できないため、他のトランザクションは待機する必要があります。この待機時間が積み重なると、システム全体の効率が低下する可能性があります。

この問題を解決するためには、ロックの粒度を調整する、トランザクションのスケジューリングを工夫するなどの工夫が必要です。

まとめ:2相ロッキングプロトコルとは?

  1. 定義: データベーストランザクションにおける並行処理を管理するプロトコル。
  2. 構成:
    • ロック取得フェーズ: 必要なロックを取得し、データにアクセスします。
    • ロック解放フェーズ: 作業完了後、ロックを解放します。
  3. 利点:
    • 整合性保証: トランザクション間でのデータ整合性を保つ。
    • 並行処理: 複数のトランザクションの同時実行をサポート。
  4. 欠点:
    • デッドロック: ロックの相互待ちによる停止の可能性。
    • 効率の問題: ロック競合による処理の遅延。

SQLやデータベースの仕組みを1から学習したい方(学び直したい方)向けに、現役エンジニア達のスキルを結集して 完全無料 のSQL教材を作成しました。

SQLは決して難しい技術ではないので、エンジニアであれば「当たり前のように」扱えて当然かも・・・?

とはいえ、案外SQLをちゃんと使ったことがない人も多いはずです。この機会に是非一度ご覧になってみてください。

このWebサイトは現役のエンジニアが以下3点を目的として運営しています。

  1. 勉強:一度理解した内容を忘れないように。
    → アウトプットは「最強のインプット」である! 
  2. 備忘:忘れたとしても後から見返せるように。
    → 未来の自分への「お手紙」を書いています。 
  3. 共有:〇〇ってこうだったんだ!の感動をシェアできるように。
    → あなたの知識は誰かにとっての「価値ある情報」です。 

副業ブログの始め方はこちらから

スポンサーリンク
DatabaseIT-Skills
シェアする
ビズドットオンラインをフォローする
タイトルとURLをコピーしました