LOCK

Name

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

Synopsis

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

入力

table

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

ACCESS SHARE MODE

Note: このモードでは問い合わせが行なわれるテーブル全体のロックを自 動的に獲得します。Postgres は、そ の文が完了した後、自動的に獲得した ACCESS SHARE ロックを開放 します。

これは、最も制限の弱いロックモードで、ACCESS EXCLUSIVE モード とのみコンフリクトします。あるテーブルに対する ALTER TABLEDROP TABLEVACUUM 文の同時実行からそのテーブルを保護 することが目的です。

ROW SHARE MODE

Note: 任意の SELECT FOR UPDATE 文によって自動的 に獲得されます。

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

ROW EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、 ACCESS EXCLUSIVE モードにコンフリクトします。このモードはある 時刻に 1 つのトランザクションのみがこのロックを保有できるとい う理由で、SHARE モードよりも制限の強いものです。

EXCLUSIVE MODE

ROW SHARE、ROW EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、 EXCLUSIVE、ACCESS EXCLUSIVE モードにコンフリクトします。この モードは SHARE ROW EXCLUSIVE よりもっと制限が強いものです。 このモードは全てのSELECT FOR UPDATE 問い合わせの同時実行をブ ロックします。

ACCESS EXCLUSIVE MODE

Note: ALTER TABLEDROP TABLE, VACUUM 文 によって自動的に獲得されます。

これは最も制限の強いロックモードで、他の全てのロックモードとコ ンフリクトし、同時に起こる全ての操作からロックしたテーブルを保 護します。

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

出力

LOCK TABLE

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

ERROR table: Table does not exist.

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

説明

Postgres は可能である限り、常に最も制限 の弱いロックモードを使用します。より強い制限を持つロックを必要とす る場合のために LOCK TABLE が用意されています。

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