LOCK <refpurpose>lock a table</refpurpose> — テーブルをロックする
LOCK [ TABLE ] [ ONLY ]name
[ * ] [, ...] [ INlockmode
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
<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 MODEROW 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
— 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 — 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を参照してください。
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
が競合するロックの解放まで待機しないことを指定します。
指定したロックがすぐに取得できない場合、トランザクションはアボートされます。
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
に対して適切な権限を持っていることが必要です。
ユーザがテーブルに対してMAINTAIN
、UPDATE
、DELETE
または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_invoker
がtrue
に設定されている場合(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
はトランザクションブロックの外側では意味がありません。
文が完了するまでしかロックは保持されません。
したがってPostgreSQLはLOCK
がトランザクションブロックの外側で使用された場合にエラーを報告します。
トランザクションブロックを定義するためには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とロック処理句を参照してください。
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';
-- 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;
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 SHARE
、ACCESS EXCLUSIVE
、SHARE UPDATE EXCLUSIVE
ロックモードを除き、PostgreSQLのロックモードとLOCK TABLE
構文はOracleのものと互換性があります。