Home Explore Blog CI



postgresql

24th chunk of `doc/src/sgml/mvcc.sgml`
93c7e563f0b1e31b80efa08103d15cf2508d577962c8bb2a0000000100000fa4
 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 &mdash; 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

Title: Enforcing Consistency with Serializable and Explicit Locks
Summary
This section discusses techniques for ensuring data consistency, including using Serializable transactions to automatically retry failed transactions and setting the default transaction isolation level to Serializable. It also covers the limitations of Serializable transactions with hot standby and logical replication, and the use of explicit blocking locks, such as SELECT FOR UPDATE and LOCK TABLE, to protect against concurrent updates and ensure data validity. Additionally, it highlights the challenges of performing global validity checks in non-serializable MVCC environments.