はじめに
データベースでは、複数のユーザーやアプリケーションが同時にデータへアクセスします。
もし制御なしに更新が行われると、以下の問題が発生します。
- 更新内容の上書き(ロストアップデート)
- 読み取りの不整合(ダーティリード)
- 処理結果の不一致
これを防ぐために、Db2ではロックによる排他制御を行います。
ロックの対象と範囲
ロックは以下の単位で取得されます。
| 対象 | 説明 |
|---|---|
| 行(Row) | 最も細かい |
| 表(Table) | 行単位制御が困難な場合 |
| 表スペース | ユーティリティなどで使用 |
- 通常のSQL:行 or 表ロック
- ユーティリティ:表スペースロックあり
- 索引にはロックは取得されない
ロック範囲が広くなるほど、並列性低下、ロック競合増加につながります。
ロックの種類と互換性
ロックにはモード(種類)があり、他のロックと同時に取得できるか(互換性)が決まっています。
基本ロックの互換性
| 要求\保持 | S(共有) | U(更新) | X(排他) |
|---|---|---|---|
| S(共有) | ○ | ○ | × |
| U(更新) | ○ | × | × |
| X(排他) | × | × | × |
- ○:同時に取得可能
- ×:待機(ロック待ち)
ポイント
- S(共有):参照用(SELECT)
- U(更新):更新前の中間ロック
- X(排他):更新用(INSERT/UPDATE/DELETE)
つまり、
- 読み取り同士は共存できる
- 更新は基本的に単独
というシンプルなルールです。
ロックのモード詳細
Db2ではさらに細かいロックモードが存在します。


×の場合、ロック取得不可能であるためロック待ちとなります。
補足
- アクセス経路や分離レベルにより取得ロックは変わる
- 表ロック+行ロックの組み合わせで制御される
ロックの保持期間
Db2におけるロックは、トランザクション単位で保持されます。
つまり、ロックは COMMIT または ROLLBACK を実行したタイミングで解放されます。
逆に言うと、これらを実行するまでロックは保持され続けます。
たとえば、UPDATE や INSERT などの更新処理では排他ロック(Xロック)が取得され、その状態のまま COMMIT しないと、他のトランザクションは同じデータにアクセスできません。
この状態が続くと、他の処理はロック待ち(Lock Wait)となり、処理遅延やタイムアウトの原因になります。
特に注意が必要なのは以下のようなケースです。
- 長時間 COMMIT されないトランザクション
- 大量データを一括更新するバッチ処理
- カーソルを開いたままの長時間処理
このような状況ではロックが長時間保持され、並行処理性能が大きく低下します。
そのため、設計および運用では以下を意識することが重要です。
- トランザクションはできるだけ短くする
- 適切なタイミングで COMMIT を実行する
- バッチ処理は分割して実行する
ロックの保持期間はシンプルな仕組みですが、性能問題や障害の原因になりやすいポイントです。
そのため、「いつロックが解放されるのか」を正しく理解しておくことが重要です。
ロックエスカレーション
ロックエスカレーションとは、多数の行ロックを1つの表ロックに変換する仕組みです。
主にメモリ(ロックリスト)の使用量を抑えるために発生します。
ロックエスカレーションは以下の動きです。
- 行ロックが大量に取得される
- メモリ使用量が増加
- 一定条件を超える
- 行ロック → 表ロックへ変換
イメージ
変換前:
A表の複数行にロック(12行目、30行目、99行目…)
変換後:
A表全体に表ロック
メモリは削減できますが、ロック範囲が一気に広がります。
ロック情報とメモリ(LOCKLIST)
Db2ではロック情報は以下のように管理されます。
- ロック情報はロック・リスト(LOCKLIST)というメモリ領域に保存
- データベース全体で1つを共有
- 最大サイズは
LOCKLISTパラメータで制御 - 各アプリケーションはこの領域を共有して使用
発生条件(原因)
ロックエスカレーションは主に2パターンで発生します。
アプリケーション単位での上限超過(maxlocks)
- 1トランザクションが大量のロックを保持
maxlocksの割合を超過- 最もロック数が多い表が対象
データベース全体のメモリ不足(locklist)
- 全体のロックメモリが
locklist上限に到達 - 最もロックを消費しているトランザクションが対象
影響
ロックエスカレーションが起きると、性能劣化のトリガーになることが多いです。
- 行単位 → 表単位になる
- 他トランザクションがその表にアクセスできなくなる
- 並行処理性能が大きく低下
回避方法
ロックエスカレーションは設計と運用で回避できます。
トランザクションを小さくする
- 頻繁にCOMMIT
- バッチ処理は分割
分離レベルを見直す
- 不要に強い分離レベルを使わない
- ロック範囲を最小化
大量更新時は明示的に表ロック
- あらかじめ表ロックを取得
- 処理後すぐCOMMIT
パラメータ調整
| パラメータ | 内容 |
|---|---|
| LOCKLIST | ロックメモリの総量 |
| MAXLOCKS | 1アプリが使える割合 |
※現在は多くの環境で AUTOMATIC がデフォルト
→ 通常は自動調整されるが、負荷が高い場合は見直し検討
まとめ
Db2のロックは以下を理解しておくことが重要です。
- ロックは排他制御の基本
- 互換性(S/U/X)が最重要
- ロック範囲が広いほど性能悪化
- COMMITしないと解放されない
- ロックエスカレーションに注意
特に、
- ロック待ち=性能問題の原因
- 未コミット=障害の原因
になりやすいため、設計段階から意識しておくことが重要です。


コメント