他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

LOCK

Name

LOCK  --  テーブルの明示的なロック

Synopsis

LOCK [ TABLE ] name [, ...]
LOCK [ TABLE ] name [, ...] IN lockmode MODE

ここで lockmode は以下のいずれかです。

	ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE |
	SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

入力

name

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

ACCESS SHARE MODE

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

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

ROW SHARE MODE

Note: SELECT...FOR UPDATEによって自動的に獲得されます。

EXCLUSIVE と ACCESS EXCLUSIVE ロックモードに競合します。

ROW EXCLUSIVE MODE

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

SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVEモードに競合します。

SHARE UPDATE EXCLUSIVE MODE

Note: (FULLなしの)VACUUM によって自動的に獲得されます。

SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE モードに競合します。このモードはスキーマの変更と VACUUM の同時実行からテーブルを保護します。

SHARE MODE

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

ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE モードに競合します。このモードは同時データ更新からテーブルを保護します。

SHARE ROW EXCLUSIVE MODE

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

ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE モードに競合します。

EXCLUSIVE MODE

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

ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE モードに競合します。このモードでは、同時 ACCESS SHAREを許します。つまりテーブルからの読み取りのみをこのロックモードを持つトランザクションと並行して処理することができます。

ACCESS EXCLUSIVE MODE

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

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

全てのロックモードに競合します。

出力

LOCK TABLE

ロックの獲得に成功しました。

ERROR name: Table does not exist.

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

説明

LOCK TABLEはトランザクションの期間内においてテーブルへの同時アクセスを制御します。PostgreSQL は、可能な時は常に最も制限の弱いロックモードを使います。 LOCK TABLEはより制限の強いロックが必要な場合のために用意されています。

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

EXCLUSIVE

排他的ロックは、他の同種のロックに権限が認められることを防ぎます。(ROW EXCLUSIVE モードはこの命名規則に完全には従いません。テーブルレベルでは共有され、特定の行の更新に関してのみ排他的なものであるからです。)

SHARE

共有ロックは、同種のロックを他が持つことを認めます。しかし、対応する排他的ロックが認められることを防ぎます。

ACCESS

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

ROW

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

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

Note: トランザクションが隔離レベル SERIALIZABLE で実行している時に、現在の実状態のデータを読むためには、何らかの DML 文を実行するより前 に LOCK TABLE 文を実行する必要があります。シリアライザブルなトランザクション側から参照するデータの状態は、最初の DML 文が開始された時点で固定されます。

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

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

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

複数のテーブルをロックする時、LOCK a, b コマンドは LOCK a; LOCK b; と同じです。テーブルは LOCK コマンドで指定された順番で、一つ一つロックされます。

注釈

LOCK ... IN ACCESS SHARE MODE には対象テーブルに対する SELECT 権限が必要です。その他の形の LOCK には全て UPDATEDELETE、またはその両方の権限が必要です。

LOCK は通常、トランザクションブロック(BEGIN...COMMIT) の内側でのみ使用されます。ロックはトランザクションの終了後すぐに削除されるからです。トランザクションブロック外部の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 を使用します。PostgreSQL はこれ もサポートしています。詳細については SET TRANSACTION を参照して下さい。

ACCESS SHARE、ACCESS EXCLUSIVE、SHARE UPDATE EXCLUSIVE ロックモードを除き、PostgreSQL のロックモードと LOCK TABLE 構文は Oracle(TM) のものと互換性があります。