@ -1,5 +1,5 @@
<!--
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.127 2009/10/27 17:11:18 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.128 2009/10/28 14:55:37 tgl Exp $
PostgreSQL documentation
PostgreSQL documentation
-->
-->
@ -1092,22 +1092,12 @@ FOR SHARE [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ]
has already locked a selected row or rows, <command>SELECT FOR
has already locked a selected row or rows, <command>SELECT FOR
UPDATE</command> will wait for the other transaction to complete,
UPDATE</command> will wait for the other transaction to complete,
and will then lock and return the updated row (or no row, if the
and will then lock and return the updated row (or no row, if the
row was deleted). For further discussion see <xref
row was deleted). Within a <literal>SERIALIZABLE</> transaction,
however, an error will be thrown if a row to be locked has changed
since the transaction started. For further discussion see <xref
linkend="mvcc">.
linkend="mvcc">.
</para>
</para>
<para>
To prevent the operation from waiting for other transactions to commit,
use the <literal>NOWAIT</> option. <command>SELECT FOR UPDATE
NOWAIT</command> reports an error, rather than waiting, if a selected row
cannot be locked immediately. Note that <literal>NOWAIT</> applies only
to the row-level lock(s) — the required <literal>ROW SHARE</literal>
table-level lock is still taken in the ordinary way (see
<xref linkend="mvcc">). You can use the <literal>NOWAIT</> option of
<xref linkend="sql-lock" endterm="sql-lock-title">
if you need to acquire the table-level lock without waiting.
</para>
<para>
<para>
<literal>FOR SHARE</literal> behaves similarly, except that it
<literal>FOR SHARE</literal> behaves similarly, except that it
acquires a shared rather than exclusive lock on each retrieved
acquires a shared rather than exclusive lock on each retrieved
@ -1117,13 +1107,26 @@ FOR SHARE [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ]
from performing <command>SELECT FOR SHARE</command>.
from performing <command>SELECT FOR SHARE</command>.
</para>
</para>
<para>
To prevent the operation from waiting for other transactions to commit,
use the <literal>NOWAIT</> option. With <literal>NOWAIT</>, the statement
reports an error, rather than waiting, if a selected row
cannot be locked immediately. Note that <literal>NOWAIT</> applies only
to the row-level lock(s) — the required <literal>ROW SHARE</literal>
table-level lock is still taken in the ordinary way (see
<xref linkend="mvcc">). You can use
<xref linkend="sql-lock" endterm="sql-lock-title">
with the <literal>NOWAIT</> option first,
if you need to acquire the table-level lock without waiting.
</para>
<para>
<para>
If specific tables are named in <literal>FOR UPDATE</literal>
If specific tables are named in <literal>FOR UPDATE</literal>
or <literal>FOR SHARE</literal>,
or <literal>FOR SHARE</literal>,
then only rows coming from those tables are locked; any other
then only rows coming from those tables are locked; any other
tables used in the <command>SELECT</command> are simply read as
tables used in the <command>SELECT</command> are simply read as
usual. A <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>
usual. A <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>
clause without a table list affects all tables used in the command.
clause without a table list affects all tables used in the statement .
If <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal> is
If <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal> is
applied to a view or sub-query, it affects all tables used in
applied to a view or sub-query, it affects all tables used in
the view or sub-query.
the view or sub-query.
@ -1151,6 +1154,36 @@ FOR SHARE [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ]
individual table rows; for example they cannot be used with aggregation.
individual table rows; for example they cannot be used with aggregation.
</para>
</para>
<para>
When <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>
appears at the top level of a <command>SELECT</> query, the rows that
are locked are exactly those that are returned by the query; in the
case of a join query, the rows locked are those that contribute to
returned join rows. In addition, rows that satisfied the query
conditions as of the query snapshot will be locked, although they
will not be returned if they have since been updated to not satisfy
the query conditions. If a <literal>LIMIT</> is used, locking stops
once enough rows have been returned to satisfy the limit (but note that
rows skipped over by <literal>OFFSET</> will get locked). Similarly,
if <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>
is used in a cursor's query, only rows actually fetched or stepped past
by the cursor will be locked.
</para>
<para>
When <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>
appears in a sub-<command>SELECT</>, the rows locked are those
returned to the outer query by the sub-query. This might involve
fewer rows than inspection of the sub-query alone would suggest,
since conditions from the outer query might be used to optimize
execution of the sub-query. For example,
<programlisting>
SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;
</programlisting>
will lock only rows having <literal>col1 = 5</>, even though that
condition is not textually within the sub-query.
</para>
<caution>
<caution>
<para>
<para>
Avoid locking a row and then modifying it within a later savepoint or
Avoid locking a row and then modifying it within a later savepoint or
@ -1177,30 +1210,26 @@ ROLLBACK TO s;
<caution>
<caution>
<para>
<para>
It is possible for a <command>SELECT</> command using both
It is possible for a <command>SELECT</> command using <literal>ORDER
<literal>LIMIT</literal> and <literal>FOR UPDATE/SHARE</literal>
BY</literal> and <literal>FOR UPDATE/SHARE</literal> to return rows out of
clauses to return fewer rows than specified by <literal>LIMIT</literal>.
order. This is because <literal>ORDER BY</> is applied first.
This is because <literal>LIMIT</> is applied first. The command
The command sorts the result, but might then block trying to obtain a lock
selects the specified number of rows,
on one or more of the rows. Once the <literal>SELECT</> unblocks, some
but might then block trying to obtain a lock on one or more of them.
of the ordering column values might have been modified, leading to those
Once the <literal>SELECT</> unblocks, the row might have been deleted
rows appearing to be out of order (though they are in order in terms
or updated so that it does not meet the query <literal>WHERE</> condition
of the original column values). This can be worked around at need by
anymore, in which case it will not be returned.
placing the <literal>FOR UPDATE/SHARE</literal> clause in a sub-query,
</para>
for example
</caution>
<programlisting>
SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
<caution>
</programlisting>
<para>
Note that this will result in locking all rows of <structname>mytable</>,
Similarly, it is possible for a <command>SELECT</> command
whereas <literal>FOR UPDATE</> at the top level would lock only the
using <literal>ORDER BY</literal> and <literal>FOR
actually returned rows. This can make for a significant performance
UPDATE/SHARE</literal> to return rows out of order. This is
difference, particularly if the <literal>ORDER BY</> is combined with
because <literal>ORDER BY</> is applied first. The command
<literal>LIMIT</> or other restrictions. So this technique is recommended
orders the result, but might then block trying to obtain a lock
only if concurrent updates of the ordering columns are expected and a
on one or more of the rows. Once the <literal>SELECT</>
strictly sorted result is required.
unblocks, one of the ordered columns might have been modified
and be returned out of order. A workaround is to perform
<command>SELECT ... FOR UPDATE/SHARE</> and then <command>SELECT
... ORDER BY</>.
</para>
</para>
</caution>
</caution>
</refsect2>
</refsect2>
@ -1541,15 +1570,28 @@ SELECT distributors.* WHERE distributors.name = 'Westward';
used by <productname>MySQL</productname>. The SQL:2008 standard
used by <productname>MySQL</productname>. The SQL:2008 standard
has introduced the clauses <literal>OFFSET ... FETCH {FIRST|NEXT}
has introduced the clauses <literal>OFFSET ... FETCH {FIRST|NEXT}
...</literal> for the same functionality, as shown above
...</literal> for the same functionality, as shown above
in <xref linkend="sql-limit" endterm="sql-limit-title">, and t his
in <xref linkend="sql-limit" endterm="sql-limit-title">. T his
syntax is also used by <productname>IBM DB2</productname>.
syntax is also used by <productname>IBM DB2</productname>.
(Applications written for <productname>Oracle</productname>
(Applications written for <productname>Oracle</productname>
frequently use a workaround involving the automatically
frequently use a workaround involving the automatically
generated <literal>rownum</literal> column, not available in
generated <literal>rownum</literal> column, which is not available in
PostgreSQL, to implement the effects of these clauses.)
PostgreSQL, to implement the effects of these clauses.)
</para>
</para>
</refsect2>
</refsect2>
<refsect2>
<title><literal>FOR UPDATE</> and <literal>FOR SHARE</></title>
<para>
Although <literal>FOR UPDATE</> appears in the SQL standard, the
standard allows it only as an option of <command>DECLARE CURSOR</>.
<productname>PostgreSQL</productname> allows it in any <command>SELECT</>
query as well as in sub-<command>SELECT</>s, but this is an extension.
The <literal>FOR SHARE</> variant, and the <literal>NOWAIT</> option,
do not appear in the standard.
</para>
</refsect2>
<refsect2>
<refsect2>
<title>Nonstandard Clauses</title>
<title>Nonstandard Clauses</title>