LOCK

Name

LOCK  --  トランザクション内部でのテーブルの明示的なロック

Synopsis

LOCK [ TABLE ] name
LOCK [ TABLE ] name IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE
LOCK [ TABLE ] name IN SHARE ROW EXCLUSIVE MODE
  

入力

name

ロックを行なう既存テーブルの名前です。

ACCESS SHARE MODE

Note: このモードでは問い合わせが行なわれるテーブル全体のロックを 自動的に獲得します。

これは、最も制限の弱いロックモードです。ACCESS EXCLUSIVE モード とのみコンフリクトします。あるテーブルに対する ALTER TABLEDROP TABLE そして VACUUM コマンドの同時実行からそのテーブルを保護するために使われます。

ROW SHARE MODE

Note: SELECT...FOR UPDATE によって自動的に 獲得されます。共有ロックですが、後で ROW EXCLUSEIVE ロック にアップグレードすることができます。

EXCLUSIVE と ACCESS EXCLUSIVE ロックモードにコンフリクトします。

ROW EXCLUSIVE MODE

Note: UPDATEDELETEINSERT 文によって自動的に獲得されます。

SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE モード にコンフリクトします。

SHARE MODE

Note: CREATE INDEX によって自動的に獲得 されます。テーブル全体を共有ロックします。

ROW EXCLUSIVE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE モードにコンフリクトします。このモードは同時更新からテーブルを保 護します。

SHARE ROW EXCLUSIVE MODE

Note: これは EXCLUSIVE MODE のようなものですが、他からの SHARE ROW ロックを許可します。

ROW EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、 ACCESS EXCLUSIVE モードにコンフリクトします。

EXCLUSIVE MODE

Note: このモードは SHARE ROW EXCLUSIVE よりも更に制限の強いものです。 全ての同時 ROW SHARE/SELECT...FOR UPDATE 問い合わせをブロック します。

ROW SHARE、ROW EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、 EXCLUSIVE、 ACCESS EXCLUSIVE モードにコンフリクトします。

ACCESS EXCLUSIVE MODE

Note: ALTER TABLEDROP TABLEVACUUM 文から自動的に獲得されます。これは最も制限の強いロック モードで、他の全てのロックモードとコンフリクトし、同時に起こ る全ての操作からロックしたテーブルを保護します。

Note: このロックモードは条件を持たない(つまり、明示的なロックモー ドオプションが付いていない)LOCK TABLE によっても獲得されます。

出力

LOCK TABLE

ロックの適用に成功しました。

ERROR name: Table does not exist.

name が存在しない 場合に返されるメッセージです。

説明

LOCK TABLE はトランザクションの持続中にテーブル への同時アクセスを管理します。Postgres は、可能な時は常に最も制限の弱いロックモードを使います。 LOCK TABLE はもっと制限の強いロックが必要な 場合のために用意されています。

RDBMS ロックは以下の用語を使います。

EXCLUSIVE

他のロックに権限が認められないようにするための排他的ロックです。

SHARE

他の人がロックを共有することを認めます。EXCLUSIVE ロック を無効にします。

ACCESS

テーブルスキーマをロックします。

ROW

個々の行をロックします。

Note: EXCLUSIVE または SHARE が指定されない場合、EXCLUSIVE である と仮定されます。ロックはトランザクションの持続する間存在します。

例えば、アプリケーションが隔離レベル READ COMMITTED でトランザクシ ョンを実行し、そのトランザクションの間テーブルにデータが存在するこ とを確実にする必要がある場合を考えてみます。これを達成するために、 問い合わせ実行前にテーブル全体に SHARE ロックモードを使用することが できます。これは同時変更からデータを保護し、現在の実状態を維持した テーブル全体に対して読みとり操作を今後行なうことができます。SHARE ロックモードは、書き込み側によって獲得されるあらゆる ROW EXCLUSIVE とコンフリクトし、 LOCK TABLE name IN SHARE MODE 文は同時書き込み操作のコミットまたはロール バックが終るまで待つからです。

Note: トランザクションが隔離レベル SERIALIZABLE で実行している時に、 現在の実状態のデータを読むためには、何らかの DML 文を実行するより前 に LOCK TABLE 文を実行する必要があります。このとき、そのトランザク ションはどんな同時変更を自身で認識できるかを定義します。

上の要求事項に加え、トランザクションがテーブル内のデータを変更する 予定であるならば、SHARE ROW EXCLUSIVE ロックモードを獲得して、次の デッドロック状態を防止しなければなりません。2 つの同時トランザクシ ョンがテーブルを SHARE モードでテーブルをロックし、そしてテーブル 内のデータを変更しようとすると、両者は(暗黙的に)ROW EXCLUSIVE ロ ックモードを取得しようとしますが、このロックモードは同時 SHARE ロ ックとコンフリクトします。

上で発生したデッドロック(2 つのトランザクションがお互いに待ってい る状態)に関する論点を続けると、デッドロック状態を防ぐために 2 つ の一般的なルールに従わなければなりません。

Note: Postgres はデッドロックを検出し、少なく ても 1 つの待ち状態のトランザクションを、デッドロックを解消するた めにロールバックします。

注釈

LOCKPostgres の言語拡張です。

ACCESS SHARE/EXCLUSIVE ロックモード以外の Postgres のロックモードと LOCK TABLE の構文は Oracle と互換性があります。

LOCK はトランザクションの内側でのみ動作します。

使用方法

外部キーテーブルへの挿入を行なう際のプライマリキーテーブルへの SHARE ロックについて説明します。

BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films 
    WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- Do ROLLBACK if record was not returned
INSERT INTO films_user_comments VALUES 
    (_id_, 'GREAT! I was waiting for it for so long!');
COMMIT WORK;
   

削除操作を行なう際にプライマリキーテーブルの SHARE ROW EXCLUSIVE ロックを取得します。

BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM films_user_comments WHERE id IN
    (SELECT id FROM films WHERE rating < 5);
DELETE FROM films WHERE rating < 5;
COMMIT WORK;
   

互換性

SQL92

SQL92 には LOCK TABLE は ありません。その代わりにトランザクションの同時性レベルを指定する SET TRANSACTION を使用します。Postgres はこれ もサポートしています。詳細については SET TRANSACTION を参照して下さい。