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.
</para>
<para>
<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.
</para>
<para>
<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.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Obtain a <literal>SHARE</literal> lock on a primary key table when going to perform
inserts into a foreign key table:
<programlisting>
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
INSERT INTO films_user_comments VALUES
(_id_, 'GREAT! I was waiting for it for so long!');
COMMIT WORK;
</programlisting>
</para>
<para>
Take a <literal>SHARE ROW EXCLUSIVE</literal> lock on a primary key table when going to perform
a delete operation:
<programlisting>
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;
</programlisting></para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
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.
</para>
<para>
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>.
</para>
</refsect1>
</refentry>