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 TABLEVACUUM 文の同時実行からそのテーブルを保護 することが目的です。

ROW SHARE MODE

Note: 任意の SELECT ...FOR UPDATE 文によって自動的 に獲得されます。 共有ロックですが、後に ROW EXCLUSIVE ロックに上がる可能性があり ます。

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

ROW EXCLUSIVE MODE

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

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

SHARE MODE

Note: CREATE INDEX 文によって自動的に獲得されます。 共有(share)は、テーブル全体をロックすることを意味します。

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

SHARE ROW EXCLUSIVE MODE

Note: これは EXCLUSIVE モードに似ていますが、他所にて 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 TABLE, VACUUM 文 によって自動的に獲得されます。 このモードは最も制限の強いロックモードで、他の全てのロック モードとコンフリクトし、全ての同時実行操作からロックされた テーブルを保護します。

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';
-- レコードが返されない場合は 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 を参照し て下さい。