]> begriffs open source - ai-pg/blob - full-docs/src/sgml/html/applevel-consistency.html
PG 18 docs from https://ftp.postgresql.org/pub/source/v18.0/postgresql-18.0-docs...
[ai-pg] / full-docs / src / sgml / html / applevel-consistency.html
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.4. Data Consistency Checks at the Application Level</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="explicit-locking.html" title="13.3. Explicit Locking" /><link rel="next" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.4. Data Consistency Checks at the Application Level</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="explicit-locking.html" title="13.3. Explicit Locking">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling">Next</a></td></tr></table><hr /></div><div class="sect1" id="APPLEVEL-CONSISTENCY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.4. Data Consistency Checks at the Application Level <a href="#APPLEVEL-CONSISTENCY" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="applevel-consistency.html#SERIALIZABLE-CONSISTENCY">13.4.1. Enforcing Consistency with Serializable Transactions</a></span></dt><dt><span class="sect2"><a href="applevel-consistency.html#NON-SERIALIZABLE-CONSISTENCY">13.4.2. Enforcing Consistency with Explicit Blocking Locks</a></span></dt></dl></div><p>
3     It is very difficult to enforce business rules regarding data integrity
4     using Read Committed transactions because the view of the data is
5     shifting with each statement, and even a single statement may not
6     restrict itself to the statement's snapshot if a write conflict occurs.
7    </p><p>
8     While a Repeatable Read transaction has a stable view of the data
9     throughout its execution, there is a subtle issue with using
10     <acronym class="acronym">MVCC</acronym> snapshots for data consistency checks, involving
11     something known as <em class="firstterm">read/write conflicts</em>.
12     If one transaction writes data and a concurrent transaction attempts
13     to read the same data (whether before or after the write), it cannot
14     see the work of the other transaction.  The reader then appears to have
15     executed first regardless of which started first or which committed
16     first.  If that is as far as it goes, there is no problem, but
17     if the reader also writes data which is read by a concurrent transaction
18     there is now a transaction which appears to have run before either of
19     the previously mentioned transactions.  If the transaction which appears
20     to have executed last actually commits first, it is very easy for a
21     cycle to appear in a graph of the order of execution of the transactions.
22     When such a cycle appears, integrity checks will not work correctly
23     without some help.
24    </p><p>
25     As mentioned in <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a>, Serializable
26     transactions are just Repeatable Read transactions which add
27     nonblocking monitoring for dangerous patterns of read/write conflicts.
28     When a pattern is detected which could cause a cycle in the apparent
29     order of execution, one of the transactions involved is rolled back to
30     break the cycle.
31    </p><div class="sect2" id="SERIALIZABLE-CONSISTENCY"><div class="titlepage"><div><div><h3 class="title">13.4.1. Enforcing Consistency with Serializable Transactions <a href="#SERIALIZABLE-CONSISTENCY" class="id_link">#</a></h3></div></div></div><p>
32      If the Serializable transaction isolation level is used for all writes
33      and for all reads which need a consistent view of the data, no other
34      effort is required to ensure consistency.  Software from other
35      environments which is written to use serializable transactions to
36      ensure consistency should <span class="quote">“<span class="quote">just work</span>”</span> in this regard in
37      <span class="productname">PostgreSQL</span>.
38     </p><p>
39      When using this technique, it will avoid creating an unnecessary burden
40      for application programmers if the application software goes through a
41      framework which automatically retries transactions which are rolled
42      back with a serialization failure.  It may be a good idea to set
43      <code class="literal">default_transaction_isolation</code> to <code class="literal">serializable</code>.
44      It would also be wise to take some action to ensure that no other
45      transaction isolation level is used, either inadvertently or to
46      subvert integrity checks, through checks of the transaction isolation
47      level in triggers.
48     </p><p>
49      See <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a> for performance suggestions.
50     </p><div class="warning"><h3 class="title">Warning: Serializable Transactions and Data Replication</h3><p>
51       This level of integrity protection using Serializable transactions
52       does not yet extend to hot standby mode (<a class="xref" href="hot-standby.html" title="26.4. Hot Standby">Section 26.4</a>)
53       or logical replicas.
54       Because of that, those using hot standby or logical replication
55       may want to use Repeatable Read and explicit locking on the primary.
56      </p></div></div><div class="sect2" id="NON-SERIALIZABLE-CONSISTENCY"><div class="titlepage"><div><div><h3 class="title">13.4.2. Enforcing Consistency with Explicit Blocking Locks <a href="#NON-SERIALIZABLE-CONSISTENCY" class="id_link">#</a></h3></div></div></div><p>
57      When non-serializable writes are possible,
58      to ensure the current validity of a row and protect it against
59      concurrent updates one must use <code class="command">SELECT FOR UPDATE</code>,
60      <code class="command">SELECT FOR SHARE</code>, or an appropriate <code class="command">LOCK
61      TABLE</code> statement.  (<code class="command">SELECT FOR UPDATE</code>
62      and <code class="command">SELECT FOR SHARE</code> lock just the
63      returned rows against concurrent updates, while <code class="command">LOCK
64      TABLE</code> locks the whole table.)  This should be taken into
65      account when porting applications to
66      <span class="productname">PostgreSQL</span> from other environments.
67     </p><p>
68      Also of note to those converting from other environments is the fact
69      that <code class="command">SELECT FOR UPDATE</code> does not ensure that a
70      concurrent transaction will not update or delete a selected row.
71      To do that in <span class="productname">PostgreSQL</span> you must actually
72      update the row, even if no values need to be changed.
73      <code class="command">SELECT FOR UPDATE</code> <span class="emphasis"><em>temporarily blocks</em></span>
74      other transactions from acquiring the same lock or executing an
75      <code class="command">UPDATE</code> or <code class="command">DELETE</code> which would
76      affect the locked row, but once the transaction holding this lock
77      commits or rolls back, a blocked transaction will proceed with the
78      conflicting operation unless an actual <code class="command">UPDATE</code> of
79      the row was performed while the lock was held.
80     </p><p>
81      Global validity checks require extra thought under
82      non-serializable <acronym class="acronym">MVCC</acronym>.
83      For example, a banking application might wish to check that the sum of
84      all credits in one table equals the sum of debits in another table,
85      when both tables are being actively updated.  Comparing the results of two
86      successive <code class="literal">SELECT sum(...)</code> commands will not work reliably in
87      Read Committed mode, since the second query will likely include the results
88      of transactions not counted by the first.  Doing the two sums in a
89      single repeatable read transaction will give an accurate picture of only the
90      effects of transactions that committed before the repeatable read transaction
91      started — but one might legitimately wonder whether the answer is still
92      relevant by the time it is delivered.  If the repeatable read transaction
93      itself applied some changes before trying to make the consistency check,
94      the usefulness of the check becomes even more debatable, since now it
95      includes some but not all post-transaction-start changes.  In such cases
96      a careful person might wish to lock all tables needed for the check,
97      in order to get an indisputable picture of current reality.  A
98      <code class="literal">SHARE</code> mode (or higher) lock guarantees that there are no
99      uncommitted changes in the locked table, other than those of the current
100      transaction.
101     </p><p>
102      Note also that if one is relying on explicit locking to prevent concurrent
103      changes, one should either use Read Committed mode, or in Repeatable Read
104      mode be careful to obtain
105      locks before performing queries.  A lock obtained by a
106      repeatable read transaction guarantees that no other transactions modifying
107      the table are still running, but if the snapshot seen by the
108      transaction predates obtaining the lock, it might predate some now-committed
109      changes in the table.  A repeatable read transaction's snapshot is actually
110      frozen at the start of its first query or data-modification command
111      (<code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
112      <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>, or
113      <code class="literal">MERGE</code>), so it is possible to obtain locks explicitly
114      before the snapshot is frozen.
115     </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="explicit-locking.html" title="13.3. Explicit Locking">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.3. Explicit Locking </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.5. Serialization Failure Handling</td></tr></table></div></body></html>