<entry align="center"></entry>
<entry align="center"></entry>
<entry align="center">X</entry>
</row>
<row>
<entry>FOR SHARE</entry>
<entry align="center"></entry>
<entry align="center"></entry>
<entry align="center">X</entry>
<entry align="center">X</entry>
</row>
<row>
<entry>FOR NO KEY UPDATE</entry>
<entry align="center"></entry>
<entry align="center">X</entry>
<entry align="center">X</entry>
<entry align="center">X</entry>
</row>
<row>
<entry>FOR UPDATE</entry>
<entry align="center">X</entry>
<entry align="center">X</entry>
<entry align="center">X</entry>
<entry align="center">X</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="locking-pages">
<title>Page-Level Locks</title>
<para>
In addition to table and row locks, page-level share/exclusive locks are
used to control read/write access to table pages in the shared buffer
pool. These locks are released immediately after a row is fetched or
updated. Application developers normally need not be concerned with
page-level locks, but they are mentioned here for completeness.
</para>
</sect2>
<sect2 id="locking-deadlocks">
<title>Deadlocks</title>
<indexterm zone="locking-deadlocks">
<primary>deadlock</primary>
</indexterm>
<para>
The use of explicit locking can increase the likelihood of
<firstterm>deadlocks</firstterm>, wherein two (or more) transactions each
hold locks that the other wants. For example, if transaction 1
acquires an exclusive lock on table A and then tries to acquire
an exclusive lock on table B, while transaction 2 has already
exclusive-locked table B and now wants an exclusive lock on table
A, then neither one can proceed.
<productname>PostgreSQL</productname> automatically detects
deadlock situations and resolves them by aborting one of the
transactions involved, allowing the other(s) to complete.
(Exactly which transaction will be aborted is difficult to
predict and should not be relied upon.)
</para>
<para>
Note that deadlocks can also occur as the result of row-level
locks (and thus, they can occur even if explicit locking is not
used). Consider the case in which two concurrent
transactions modify a table. The first transaction executes:
<screen>
UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;
</screen>
This acquires a row-level lock on the row with the specified
account number. Then, the second transaction executes:
<screen>
UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;
</screen>
The first <command>UPDATE</command> statement successfully
acquires a row-level lock on the specified row, so it succeeds in
updating that row. However, the second <command>UPDATE</command>
statement finds that the row it is attempting to update has
already been locked, so it waits for the transaction that
acquired the lock to complete. Transaction two is now waiting on
transaction one to complete before it continues execution. Now,
transaction one executes:
<screen>
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
</screen>
Transaction one attempts to acquire a row-level lock on the
specified row, but it cannot: transaction two already holds such
a lock. So it waits for transaction two to complete. Thus,
transaction one is blocked on transaction two, and transaction
two is blocked on transaction one: a deadlock
condition. <productname>PostgreSQL</productname> will detect this
situation and abort one of the transactions.
</para>
<para>
The best defense against