use serializable transactions to
ensure consistency should <quote>just work</quote> in this regard in
<productname>PostgreSQL</productname>.
</para>
<para>
When using this technique, it will avoid creating an unnecessary burden
for application programmers if the application software goes through a
framework which automatically retries transactions which are rolled
back with a serialization failure. It may be a good idea to set
<literal>default_transaction_isolation</literal> to <literal>serializable</literal>.
It would also be wise to take some action to ensure that no other
transaction isolation level is used, either inadvertently or to
subvert integrity checks, through checks of the transaction isolation
level in triggers.
</para>
<para>
See <xref linkend="xact-serializable"/> for performance suggestions.
</para>
<warning>
<title>Warning: Serializable Transactions and Data Replication</title>
<para>
This level of integrity protection using Serializable transactions
does not yet extend to hot standby mode (<xref linkend="hot-standby"/>)
or logical replicas.
Because of that, those using hot standby or logical replication
may want to use Repeatable Read and explicit locking on the primary.
</para>
</warning>
</sect2>
<sect2 id="non-serializable-consistency">
<title>Enforcing Consistency with Explicit Blocking Locks</title>
<para>
When non-serializable writes are possible,
to ensure the current validity of a row and protect it against
concurrent updates one must use <command>SELECT FOR UPDATE</command>,
<command>SELECT FOR SHARE</command>, or an appropriate <command>LOCK
TABLE</command> statement. (<command>SELECT FOR UPDATE</command>
and <command>SELECT FOR SHARE</command> lock just the
returned rows against concurrent updates, while <command>LOCK
TABLE</command> locks the whole table.) This should be taken into
account when porting applications to
<productname>PostgreSQL</productname> from other environments.
</para>
<para>
Also of note to those converting from other environments is the fact
that <command>SELECT FOR UPDATE</command> does not ensure that a
concurrent transaction will not update or delete a selected row.
To do that in <productname>PostgreSQL</productname> you must actually
update the row, even if no values need to be changed.
<command>SELECT FOR UPDATE</command> <emphasis>temporarily blocks</emphasis>
other transactions from acquiring the same lock or executing an
<command>UPDATE</command> or <command>DELETE</command> which would
affect the locked row, but once the transaction holding this lock
commits or rolls back, a blocked transaction will proceed with the
conflicting operation unless an actual <command>UPDATE</command> of
the row was performed while the lock was held.
</para>
<para>
Global validity checks require extra thought under
non-serializable <acronym>MVCC</acronym>.
For example, a banking application might wish to check that the sum of
all credits in one table equals the sum of debits in another table,
when both tables are being actively updated. Comparing the results of two
successive <literal>SELECT sum(...)</literal> commands will not work reliably in
Read Committed mode, since the second query will likely include the results
of transactions not counted by the first. Doing the two sums in a
single repeatable read transaction will give an accurate picture of only the
effects of transactions that committed before the repeatable read transaction
started — but one might legitimately wonder whether the answer is still
relevant by the time it is delivered. If the repeatable read transaction
itself applied some changes before trying to make the consistency