Committed mode provides.
</para>
</sect2>
<sect2 id="xact-repeatable-read">
<title>Repeatable Read Isolation Level</title>
<indexterm>
<primary>transaction isolation level</primary>
<secondary>repeatable read</secondary>
</indexterm>
<indexterm>
<primary>repeatable read</primary>
</indexterm>
<para>
The <firstterm>Repeatable Read</firstterm> isolation level only sees
data committed before the transaction began; it never sees either
uncommitted data or changes committed by concurrent transactions during
the transaction's execution. (However, each query does see the
effects of previous updates executed within its own transaction,
even though they are not yet committed.) This is a stronger
guarantee than is required by the <acronym>SQL</acronym> standard
for this isolation level, and prevents all of the phenomena described
in <xref linkend="mvcc-isolevel-table"/> except for serialization
anomalies. As mentioned above, this is
specifically allowed by the standard, which only describes the
<emphasis>minimum</emphasis> protections each isolation level must
provide.
</para>
<para>
This level is different from Read Committed in that a query in a
repeatable read transaction sees a snapshot as of the start of the
first non-transaction-control statement in the
<emphasis>transaction</emphasis>, not as of the start
of the current statement within the transaction. Thus, successive
<command>SELECT</command> commands within a <emphasis>single</emphasis>
transaction see the same data, i.e., they do not see changes made by
other transactions that committed after their own transaction started.
</para>
<para>
Applications using this level must be prepared to retry transactions
due to serialization failures.
</para>
<para>
<command>UPDATE</command>, <command>DELETE</command>,
<command>MERGE</command>, <command>SELECT FOR UPDATE</command>,
and <command>SELECT FOR SHARE</command> commands
behave the same as <command>SELECT</command>
in terms of searching for target rows: they will only find target rows
that were committed as of the transaction start time. However, such a
target row might have already been updated (or deleted or locked) by
another concurrent transaction by the time it is found. In this case, the
repeatable read transaction will wait for the first updating transaction to commit or
roll back (if it is still in progress). If the first updater rolls back,
then its effects are negated and the repeatable read transaction can proceed
with updating the originally found row. But if the first updater commits
(and actually updated or deleted the row, not just locked it)
then the repeatable read transaction will be rolled back with the message
<screen>
ERROR: could not serialize access due to concurrent update
</screen>
because a repeatable read transaction cannot modify or lock rows changed by
other transactions after the repeatable read transaction began.
</para>
<para>
When an application receives this error message, it should abort
the current transaction and retry the whole transaction from
the beginning. The second time through, the transaction will see the
previously-committed change as part of its initial view of the database,
so there is no logical conflict in using the new version of the row
as the starting point for the new transaction's update.
</para>
<para>
Note that only updating transactions might need to be retried; read-only
transactions will never have serialization conflicts.
</para>
<para>
The Repeatable Read mode provides a rigorous guarantee that each
transaction sees a completely stable view of the database. However,
this view will not necessarily always be consistent with some serial
(one at a time) execution of concurrent transactions