mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Update read committed documentation to better explain undesirable
behavior of concurrent commands in cases where rows are being added and removed from matching query criteria. Minor word-smithing.
This commit is contained in:
parent
649a1252b7
commit
d8a30eca2e
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.69 2007/02/18 01:21:49 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.70 2009/02/04 16:05:50 momjian Exp $ -->
|
||||||
|
|
||||||
<chapter id="mvcc">
|
<chapter id="mvcc">
|
||||||
<title>Concurrency Control</title>
|
<title>Concurrency Control</title>
|
||||||
@ -239,19 +239,19 @@
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<firstterm>Read Committed</firstterm>
|
<firstterm>Read Committed</firstterm> is the default isolation
|
||||||
is the default isolation level in <productname>PostgreSQL</productname>.
|
level in <productname>PostgreSQL</productname>. When a transaction
|
||||||
When a transaction runs on this isolation level,
|
uses this isolation level, a <command>SELECT</command> query
|
||||||
a <command>SELECT</command> query sees only data committed before the
|
(without a <literal>FOR UPDATE/SHARE</> clause) sees only data
|
||||||
query began; it never sees either uncommitted data or changes committed
|
committed before the query began; it never sees either uncommitted
|
||||||
during query execution by concurrent transactions. (However, the
|
data or changes committed during query execution by concurrent
|
||||||
<command>SELECT</command> does see the effects of previous updates
|
transactions. In effect, a <command>SELECT</command> query sees
|
||||||
executed within its own transaction, even though they are not yet
|
a snapshot of the database as of the instant the query begins to
|
||||||
committed.) In effect, a <command>SELECT</command> query
|
run. However, <command>SELECT</command> does see the effects
|
||||||
sees a snapshot of the database as of the instant that that query
|
of previous updates executed within its own transaction, even
|
||||||
begins to run. Notice that two successive <command>SELECT</command> commands can
|
though they are not yet committed. Also note that two successive
|
||||||
see different data, even though they are within a single transaction, if
|
<command>SELECT</command> commands can see different data, even
|
||||||
other transactions
|
though they are within a single transaction, if other transactions
|
||||||
commit changes during execution of the first <command>SELECT</command>.
|
commit changes during execution of the first <command>SELECT</command>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -271,22 +271,22 @@
|
|||||||
otherwise it will attempt to apply its operation to the updated version of
|
otherwise it will attempt to apply its operation to the updated version of
|
||||||
the row. The search condition of the command (the <literal>WHERE</> clause) is
|
the row. The search condition of the command (the <literal>WHERE</> clause) is
|
||||||
re-evaluated to see if the updated version of the row still matches the
|
re-evaluated to see if the updated version of the row still matches the
|
||||||
search condition. If so, the second updater proceeds with its operation,
|
search condition. If so, the second updater proceeds with its operation
|
||||||
starting from the updated version of the row. (In the case of
|
using the updated version of the row. In the case of
|
||||||
<command>SELECT FOR UPDATE</command> and <command>SELECT FOR
|
<command>SELECT FOR UPDATE</command> and <command>SELECT FOR
|
||||||
SHARE</command>, that means it is the updated version of the row that is
|
SHARE</command>, this means it is the updated version of the row that is
|
||||||
locked and returned to the client.)
|
locked and returned to the client.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Because of the above rule, it is possible for an updating command to see an
|
Because of the above rule, it is possible for an updating command to see an
|
||||||
inconsistent snapshot: it can see the effects of concurrent updating
|
inconsistent snapshot: it can see the effects of concurrent updating
|
||||||
commands that affected the same rows it is trying to update, but it
|
commands on the same rows it is trying to update, but it
|
||||||
does not see effects of those commands on other rows in the database.
|
does not see effects of those commands on other rows in the database.
|
||||||
This behavior makes Read Committed mode unsuitable for commands that
|
This behavior makes Read Committed mode unsuitable for commands that
|
||||||
involve complex search conditions. However, it is just right for simpler
|
involve complex search conditions; however, it is just right for simpler
|
||||||
cases. For example, consider updating bank balances with transactions
|
cases. For example, consider updating bank balances with transactions
|
||||||
like
|
like:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
BEGIN;
|
BEGIN;
|
||||||
@ -303,20 +303,45 @@ COMMIT;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Since in Read Committed mode each new command starts with a new snapshot
|
More complex usage can produce undesirable results in Read Committed
|
||||||
that includes all transactions committed up to that instant, subsequent
|
mode. For example, consider a <command>DELETE</command> command
|
||||||
commands in the same transaction will see the effects of the committed
|
operating on data that is being both added and removed from its
|
||||||
concurrent transaction in any case. The point at issue here is whether
|
restriction criteria by another command, e.g. assume
|
||||||
or not within a <emphasis>single</> command we see an absolutely consistent
|
<literal>website</literal> is a two-row table with
|
||||||
view of the database.
|
<literal>website.hits</literal> equaling <literal>9</literal> and
|
||||||
|
<literal>10</literal>:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
BEGIN;
|
||||||
|
UPDATE website SET hits = hits + 1;
|
||||||
|
-- run from another session: DELETE FROM website WHERE hits = 10;
|
||||||
|
COMMIT;
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
The <command>DELETE</command> will have no effect even though
|
||||||
|
there is a <literal>website.hits = 10</literal> row before and
|
||||||
|
after the <command>UPDATE</command>. This occurs because the
|
||||||
|
pre-update row value <literal>9</> is skipped, and when the
|
||||||
|
<command>UPDATE</command> completes and <command>DELETE</command>
|
||||||
|
obtains a lock, the new row value is no longer <literal>10</> but
|
||||||
|
<literal>11</>, which no longer matches the criteria.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The partial transaction isolation provided by Read Committed mode is
|
Because Read Committed mode starts each command with a new snapshot
|
||||||
adequate for many applications, and this mode is fast and simple to use.
|
that includes all transactions committed up to that instant,
|
||||||
However, for applications that do complex queries and updates, it might
|
subsequent commands in the same transaction will see the effects
|
||||||
be necessary to guarantee a more rigorously consistent view of the
|
of the committed concurrent transaction in any case. The point
|
||||||
database than the Read Committed mode provides.
|
at issue above is whether or not a <emphasis>single</> command
|
||||||
|
sees an absolutely consistent view of the database.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The partial transaction isolation provided by Read Committed mode
|
||||||
|
is adequate for many applications, and this mode is fast and simple
|
||||||
|
to use; however, it is not sufficient for all cases. Applications
|
||||||
|
that do complex queries and updates might require a more rigorously
|
||||||
|
consistent view of the database than Read Committed mode provides.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user