.\\" auto-generated by docbook2man-spec $Revision: 1.2 $
.TH "LOCK" "" "2005-01-19" "SQL - 言語" "SQL コマンド"
.SH NAME
LOCK \- テーブルのロック

.SH SYNOPSIS
.sp
.nf
LOCK [ TABLE ] \fIname\fR [, ...] [ IN \fIlockmode\fR MODE ] [ NOWAIT ]

ここで\fIlockmode\fRは以下のいずれかです。

    ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
    | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
.sp
.fi
.SH "説明"
.PP
\fBLOCK TABLE\fRはテーブルレベルのロックを獲得し、必要であれば競合するロックが解除されるまで待機します。
NOWAITが指定された場合、\fBLOCK TABLE\fRは対象のロックが獲得できるまで待機しません。
すぐに獲得できなければ、このコマンドを中止し、エラーを出力します。
ロックは、一度取得されると現行のトランザクションが完了するまで保持されます。 
(\fBUNLOCK TABLE\fRといったコマンドはありません。
ロックはトランザクションの終了時に常に解除されます。)
.PP
テーブルを参照するコマンドのために自動的にロックを獲得する場合、PostgreSQLは常に使用可能な一番弱いロックモードを使用します。
\fBLOCK TABLE\fRはより制限の強いロックが必要な場合のために用意されています。
例えば、アプリケーションが隔離レベルREAD COMMITTEDでトランザクションを実行し、そのトランザクションの期間中テーブルのデータの安定性を確実にする必要がある場合を考えてみます。
これを達成するために、問い合わせ実行前にテーブル全体にSHAREロックモードを使用することができます。 
これにより、データが同時に変更されるのを防ぎ、それ以降のテーブルの読み取りを安定させることができます。
なぜならSHAREロックモードは書き込み側が獲得するROW EXCLUSIVEロックと競合するので\fBLOCK TABLE \fIname\fB IN SHARE MODE\fR文は、ROW EXCLUSIVEの同時保持者全てのコミットまたはロールバックするのを待つからです。 
このように、一度ロックを獲得すると、コミットされていない状態の書き込みはなくなり、ユーザがロックを解除するまで誰も書き込みを開始することはできません。
.PP
シリアライザブル隔離レベルでのトランザクション実行中にこれと同様の効果を得るには、全ての\fBSELECT\fR文とデータ更新用の文を実行する前に\fBLOCK TABLE\fR文を実行する必要があります。 
シリアライザブルなトランザクション側から参照するデータの状態は、最初の\fBSELECT\fR文またはデータ更新用文が開始された時点で固定されます。
トランザクション内で後で\fBLOCK TABLE\fRを行っても同時書き込みを防ぎますが、トランザクションの読み込み対象のデータがコミットされた最新の値に対応しているかは保証されません。
.PP
このようなトランザクションでテーブル内データを変更する場合は、SHAREモードではなくSHARE ROW EXCLUSIVEロックモードを使用する必要があります。 
これによって、この種のトランザクションが同時に複数実行されることがなくなります。
SHARE ROW EXCLUSIVEを使用しないと、デッドロックが発生する可能性があります。
つまり、2つのトランザクションの両方がSHAREモードを獲得したものの、実際に更新を行うためのROW EXCLUSIVEモードを獲得することができないような状態になる可能性があります。
(トランザクション自身のロックは競合しないので、トランザクションはSHAREモードを保持している時にROW EXCLUSIVEを獲得することができます。
しかし、他のトランザクションがSHAREモードを保持している時にはROW EXCLUSIVEを獲得することはできません。)
デッドロックを回避するために、確実に全てのトランザクションは同一オブジェクトに対して同一の順番でロックを取得してください。
また、1つのオブジェクトに対して複数のロックモードを呼び出す場合、トランザクションは常に最も制限の強いモードを最初に取得しなければなりません。
.PP
ロックモードとロック取得方針についてのより詳細についてはthe documentationを参照してください。
.SH "パラメータ"
.TP
\fB\fIname\fB\fR
ロックする既存のテーブルの名前です (スキーマ修飾名でも可)。

LOCK a, b;というコマンドはLOCK TABLE a; LOCK TABLE b;と同じです。
テーブルは1つ1つ\fBLOCK\fRで指定された順番でロックされます。
.TP
\fB\fIlockmode\fB\fR
このロックモードで、取得するロックが競合するロックが何かを規定します。
ロックモードについては、the documentationで説明します。

ロックモードを指定しない場合、もっとも制限が強いACCESS EXCLUSIVEが使用されます。
.TP
\fBNOWAIT\fR
\fBLOCK TABLE\fRが競合するロックの開放を待機してはならないことを指定します。
指定したロック(複数可)を待機することなく、すぐに獲得できない場合、トランザクションはアボートします。
.SH "注釈"
.PP
LOCK TABLE ... IN ACCESS SHARE MODEには、対象テーブルのSELECT権限が必要です。
他の形式の\fBLOCK\fRには、UPDATEかDELETE、あるいはその両方の権限が必要です。
.PP
\fBLOCK TABLE\fRはトランザクションブロック内部(\fBBEGIN\fR/\fBCOMMIT\fRの組合せ)でのみ有効です。
従って、トランザクションが終了するとロックも削除されます。
トランザクションブロックの外部の\fBLOCK TABLE\fRコマンドはそのコマンドのみのトランザクションを形成しますので、このロックは取得後すぐに削除されます。
.PP
\fBLOCK\fRはテーブルレベルのロックのみを扱います。
そのため、モード名にROWが含まれるのは適切ではありません。
これらのモード名によって、ロックされたテーブル内での行レベルのロックを獲得しようとしていると、通常は解釈されてしまうでしょう。
また、ROW EXCLUSIVEモードは共有可能なロックです。
\fBLOCK TABLE\fRに関しては、全てのロックモードが同じ意味を持っていることに注意してください。
違うのは、どのモードがどのモードと競合するかという規則だけです。
実際の行レベルロックの獲得方法については\fBSELECT\fRマニュアルページのthe documentationとFOR UPDATE 句 [\fBselect\fR(l)]を参照してください。
.SH "例"
.PP
外部キーテーブルへの挿入を行なう際に、プライマリキーテーブルへのSHAREロックを獲得します。
.sp
.nf
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;
.sp
.fi
.PP
削除操作を行なう際にプライマリキーテーブルのSHARE ROW EXCLUSIVEロックを取得します。
.sp
.nf
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;
.sp
.fi
.SH "互換性"
.PP
標準SQLには\fBLOCK TABLE\fRはありません。
その代わりにトランザクションの同時性レベルを指定する\fBSET TRANSACTION\fRを使用します。
PostgreSQLはこれもサポートしています。
詳細はSET TRANSACTION [\fBset_transaction\fR(l)]を参照してください。
.PP
ACCESS SHARE、ACCESS EXCLUSIVE、SHARE UPDATE EXCLUSIVEロックモードを除き、PostgreSQLのロックモードと\fBLOCK TABLE\fR構文はOracleのものと互換性があります。
