バージョンごとのドキュメント一覧

LOCK

LOCK <refpurpose>lock a table</refpurpose> — テーブルをロックする

概要

LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]


<phrase>where <replaceable class="parameter">lockmode</replaceable> is one of:</phrase>

ここでlockmodeには以下のいずれかが入ります。

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

説明

<title>Description</title>

<command>LOCK TABLE</command> obtains a table-level lock, waiting if necessary for any conflicting locks to be released. If <literal>NOWAIT</literal> is specified, <command>LOCK TABLE</command> does not wait to acquire the desired lock: if it cannot be acquired immediately, the command is aborted and an error is emitted. Once obtained, the lock is held for the remainder of the current transaction. (There is no <command>UNLOCK TABLE</command> command; locks are always released at transaction end.) LOCK TABLEはテーブルレベルのロックを取得します。必要であれば競合するロックが解除されるまで待機します。 NOWAITが指定された場合は、LOCK TABLEは対象のロックを取得できるまで待機せず、すぐにロックが取得できなければ、このコマンドを中止し、エラーを出力します。 ロックは、一度取得されると現行のトランザクションが完了するまで保持されます (UNLOCK TABLEといったコマンドはありません。 ロックが解除されるのは常にトランザクションの終了時です)。

When a view is locked, all relations appearing in the view definition query are also locked recursively with the same lock mode. ビューがロックされると、ビューを定義する問い合わせに現れるテーブルもすべて同じロックモードで再帰的にロックされます。

When acquiring locks automatically for commands that reference tables, <productname>PostgreSQL</productname> always uses the least restrictive lock mode possible. <command>LOCK TABLE</command> provides for cases when you might need more restrictive locking. For example, suppose an application runs a transaction at the <literal>READ COMMITTED</literal> isolation level and needs to ensure that data in a table remains stable for the duration of the transaction. To achieve this you could obtain <literal>SHARE</literal> lock mode over the table before querying. This will prevent concurrent data changes and ensure subsequent reads of the table see a stable view of committed data, because <literal>SHARE</literal> lock mode conflicts with the <literal>ROW EXCLUSIVE</literal> lock acquired by writers, and your <command>LOCK TABLE <replaceable class="parameter">name</replaceable> IN SHARE MODE</command> statement will wait until any concurrent holders of <literal>ROW EXCLUSIVE</literal> mode locks commit or roll back. Thus, once you obtain the lock, there are no uncommitted writes outstanding; furthermore none can begin until you release the lock. テーブルを参照するコマンドのために自動的にロックを取得する場合、PostgreSQLは使用可能な一番弱いロックモードを常に使用します。 LOCK TABLEはより制限の強いロックが必要な場合のために用意されています。 例えば、分離レベルREAD COMMITTEDでトランザクションを実行するアプリケーションで、トランザクションの間中、テーブルのデータを確実に安定させる必要がある場合を考えます。 この場合、問い合わせ実行前にテーブル全体にSHAREロックモードを使用します。 これにより、データが同時に変更されるのを防ぎ、それ以降のテーブルの読み取りは、コミット済みの安定したデータが見えるようになります。 なぜならSHAREロックモードは書き込み側が取得するROW EXCLUSIVEロックと競合するので、LOCK TABLE name IN SHARE MODE文は、ROW EXCLUSIVEを保持しているトランザクションがコミットまたはロールバックされるのを待つからです。 したがって、一度ロックを取得してしまえば、コミットされていない状態の書き込みは存在しないことになります。さらに、ロックを解除するまで他のアプリケーションは書き込みを開始することができません。

To achieve a similar effect when running a transaction at the <literal>REPEATABLE READ</literal> or <literal>SERIALIZABLE</literal> isolation level, you have to execute the <command>LOCK TABLE</command> statement before executing any <command>SELECT</command> or data modification statement. A <literal>REPEATABLE READ</literal> or <literal>SERIALIZABLE</literal> transaction's view of data will be frozen when its first <command>SELECT</command> or data modification statement begins. A <command>LOCK TABLE</command> later in the transaction will still prevent concurrent writes &mdash; but it won't ensure that what the transaction reads corresponds to the latest committed values. REPEATABLE READまたはSERIALIZABLE分離レベルで実行しているトランザクションで同様の効果を得るには、全てのSELECT文とデータを更新する文を実行する前にLOCK TABLE文を実行する必要があります。 REPEATABLE READまたはSERIALIZABLEトランザクション側から参照するデータの状態は、最初にSELECT文またはデータ更新用文が開始された時点で固定されます。 後からトランザクション内でLOCK TABLEを実行した場合も同時書き込みを防ぐことはできますが、トランザクションの読み込み対象データの値がコミットされた最新の値であることは保証されません。

If a transaction of this sort is going to change the data in the table, then it should use <literal>SHARE ROW EXCLUSIVE</literal> lock mode instead of <literal>SHARE</literal> mode. This ensures that only one transaction of this type runs at a time. Without this, a deadlock is possible: two transactions might both acquire <literal>SHARE</literal> mode, and then be unable to also acquire <literal>ROW EXCLUSIVE</literal> mode to actually perform their updates. (Note that a transaction's own locks never conflict, so a transaction can acquire <literal>ROW EXCLUSIVE</literal> mode when it holds <literal>SHARE</literal> mode &mdash; but not if anyone else holds <literal>SHARE</literal> mode.) To avoid deadlocks, make sure all transactions acquire locks on the same objects in the same order, and if multiple lock modes are involved for a single object, then transactions should always acquire the most restrictive mode first. このようなトランザクションでテーブルのデータを変更する場合は、SHAREモードではなくSHARE ROW EXCLUSIVEロックモードを使用する必要があります。 これによって、この種のトランザクションが同時に複数実行されることがなくなります。 SHARE ROW EXCLUSIVEを使用しないと、デッドロックが発生する可能性があります。 2つのトランザクションの両方が、SHAREモードを取得していながら、実際の更新に必要なROW EXCLUSIVEモードを取得できない状態になる可能性があるためです (トランザクション自身が所有しているロック間は競合しないので、トランザクションはSHAREモードを保持している間もROW EXCLUSIVEを獲得することができます。 しかし、他のトランザクションがSHAREモードを保持している時にはROW EXCLUSIVEを獲得することはできません)。 デッドロックを回避するには、全てのトランザクションが、必ず同一オブジェクトに対して同一の順番でロックを取得するようにしてください。 また、1つのオブジェクトに対して複数のロックモードを呼び出す場合、トランザクションは常に最も制限の強いモードを最初に取得するべきです。

More information about the lock modes and locking strategies can be found in <xref linkend="explicit-locking"/>. ロックモードとロック取得方針についてのより詳細については13.3を参照してください。

パラメータ

<title>Parameters</title>
name

The name (optionally schema-qualified) of an existing table to lock. If <literal>ONLY</literal> is specified before the table name, only that table is locked. If <literal>ONLY</literal> is not specified, the table and all its descendant tables (if any) are locked. Optionally, <literal>*</literal> can be specified after the table name to explicitly indicate that descendant tables are included. ロックする既存のテーブルの名前です(スキーマ修飾名も可)。 テーブル名の前にONLYが指定された場合、そのテーブルのみをロックします。 ONLYが指定されない場合、そのテーブルとすべての子テーブル(もしあれば)をロックします。 オプションで、テーブル名の後に*を指定することで、明示的に継承するテーブルも含まれることを示すことができます。

The command <literal>LOCK TABLE a, b;</literal> is equivalent to <literal>LOCK TABLE a; LOCK TABLE b;</literal>. The tables are locked one-by-one in the order specified in the <command>LOCK TABLE</command> command. LOCK a, b;というコマンドはLOCK TABLE a; LOCK TABLE b;と同じです。 テーブルは1つひとつLOCKで指定された順番でロックされます。

lockmode

The lock mode specifies which locks this lock conflicts with. Lock modes are described in <xref linkend="explicit-locking"/>. ロックモードには、取得するロックと競合するロックを指定します。 ロックモードについては、13.3で説明します。

If no lock mode is specified, then <literal>ACCESS EXCLUSIVE</literal>, the most restrictive mode, is used. ロックモードを指定しない場合、最も制限が強いACCESS EXCLUSIVEが使用されます。

NOWAIT

Specifies that <command>LOCK TABLE</command> should not wait for any conflicting locks to be released: if the specified lock(s) cannot be acquired immediately without waiting, the transaction is aborted. LOCK TABLEが競合するロックの解放まで待機しないことを指定します。 指定したロックがすぐに取得できない場合、トランザクションはアボートされます。

注釈

<title>Notes</title>

To lock a table, the user must have the right privilege for the specified <replaceable class="parameter">lockmode</replaceable>. If the user has <literal>MAINTAIN</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>, or <literal>TRUNCATE</literal> privileges on the table, any <replaceable class="parameter">lockmode</replaceable> is permitted. If the user has <literal>INSERT</literal> privileges on the table, <literal>ROW EXCLUSIVE MODE</literal> (or a less-conflicting mode as described in <xref linkend="explicit-locking"/>) is permitted. If a user has <literal>SELECT</literal> privileges on the table, <literal>ACCESS SHARE MODE</literal> is permitted. テーブルをロックするには、ユーザが指定したlockmodeに対して適切な権限を持っていることが必要です。 ユーザがテーブルに対してMAINTAINUPDATEDELETEまたはTRUNCATE権限を持っている場合、任意のlockmodeが許可されます。 ユーザがテーブルに対してINSERT権限を持っている場合、ROW EXCLUSIVE MODE(または13.3で説明されている競合のより少ないモード)が許可されます。 ユーザがテーブルに対してSELECT権限を持っている場合、ACCESS SHARE MODEが許可されます。

The user performing the lock on the view must have the corresponding privilege on the view. In addition, by default, the view's owner must have the relevant privileges on the underlying base relations, whereas the user performing the lock does not need any permissions on the underlying base relations. However, if the view has <literal>security_invoker</literal> set to <literal>true</literal> (see <link linkend="sql-createview"><command>CREATE VIEW</command></link>), the user performing the lock, rather than the view owner, must have the relevant privileges on the underlying base relations. ビューに対してロックを実行するユーザはビューに対して対応する権限を持っていなければなりません。 さらに、デフォルトでは、ビューの所有者は元になる基底リレーションに対する関連する権限を持っていなければなりませんが、ロックを実行するユーザは元になる基底リレーションに対する権限を必要としません。 ただし、ビューのsecurity_invokertrueに設定されている場合(CREATE VIEWを参照してください)、ビュー所有者ではなくロックを実行するユーザは元になる基底リレーションに対する関連する権限を持っていなければなりません。

<command>LOCK TABLE</command> is useless outside a transaction block: the lock would remain held only to the completion of the statement. Therefore <productname>PostgreSQL</productname> reports an error if <command>LOCK</command> is used outside a transaction block. Use <link linkend="sql-begin"><command>BEGIN</command></link> and <link linkend="sql-commit"><command>COMMIT</command></link> (or <link linkend="sql-rollback"><command>ROLLBACK</command></link>) to define a transaction block. LOCK TABLEはトランザクションブロックの外側では意味がありません。 文が完了するまでしかロックは保持されません。 したがってPostgreSQLLOCKがトランザクションブロックの外側で使用された場合にエラーを報告します。 トランザクションブロックを定義するためにはBEGINおよびCOMMIT(またはROLLBACK)を使用してください。

<command>LOCK TABLE</command> only deals with table-level locks, and so the mode names involving <literal>ROW</literal> are all misnomers. These mode names should generally be read as indicating the intention of the user to acquire row-level locks within the locked table. Also, <literal>ROW EXCLUSIVE</literal> mode is a shareable table lock. Keep in mind that all the lock modes have identical semantics so far as <command>LOCK TABLE</command> is concerned, differing only in the rules about which modes conflict with which. For information on how to acquire an actual row-level lock, see <xref linkend="locking-rows"/> and <xref linkend="sql-for-update-share"/> in the <xref linkend="sql-select"/> documentation. LOCKが扱うのはテーブルレベルのロックのみです。 そのため、モード名にROWが含まれるのは適切ではありません。 これらのモード名は、普通は、ロックされたテーブル内で行レベルのロックを取得する意図と解釈されるでしょう。 また、ROW EXCLUSIVEモードは共有可能なテーブルロックです。 LOCK TABLEに関しては、全てのロックモードが同じ意味を持っており、違うのは、どのモードがどのモードと競合するかという規則だけであることに注意して下さい。 実際の行レベルでのロックを獲得する方法については、SELECTの文書の13.3.2ロック処理句を参照してください。

<title>Examples</title>

Obtain a <literal>SHARE</literal> lock on a primary key table when going to perform inserts into a foreign key table: 外部キーテーブルへの挿入を行う際に、主キーテーブルへのSHAREロックを獲得します。

BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
    WHERE name = 'Star Wars: Episode I - The Phantom Menace';

&#45;- Do ROLLBACK if record was not returned

-- レコードがなければROLLBACKしてください。
INSERT INTO films_user_comments VALUES
    (_id_, 'GREAT! I was waiting for it for so long!');
COMMIT WORK;

Take a <literal>SHARE ROW EXCLUSIVE</literal> lock on a primary key table when going to perform a delete operation: 削除操作を行う際に主キーテーブルの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;

互換性

<title>Compatibility</title>

There is no <command>LOCK TABLE</command> in the SQL standard, which instead uses <command>SET TRANSACTION</command> to specify concurrency levels on transactions. <productname>PostgreSQL</productname> supports that too; see <xref linkend="sql-set-transaction"/> for details. 標準SQLにはLOCK TABLEはありません。 その代わりにトランザクションの同時性レベルを指定するSET TRANSACTIONが使用されます。 PostgreSQLはこのコマンドもサポートしています。詳細はSET TRANSACTIONを参照してください。

Except for <literal>ACCESS SHARE</literal>, <literal>ACCESS EXCLUSIVE</literal>, and <literal>SHARE UPDATE EXCLUSIVE</literal> lock modes, the <productname>PostgreSQL</productname> lock modes and the <command>LOCK TABLE</command> syntax are compatible with those present in <productname>Oracle</productname>. ACCESS SHAREACCESS EXCLUSIVESHARE UPDATE EXCLUSIVEロックモードを除き、PostgreSQLのロックモードとLOCK TABLE構文はOracleのものと互換性があります。