aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-12-18 20:40:24 +0000
committerBruce Momjian <bruce@momjian.us>2002-12-18 20:40:24 +0000
commite77443fde0b8310fdf807b0e7142b76330ad6ecd (patch)
tree4b6edc76292f3834f43d8a091e66a3766e9812ad
parent088f3ccefd327f27502dac37ca0a8cdf43554e9a (diff)
downloadpostgresql-e77443fde0b8310fdf807b0e7142b76330ad6ecd.tar.gz
postgresql-e77443fde0b8310fdf807b0e7142b76330ad6ecd.zip
MVCC doc improvements:
> I'm not objecting to improving the text. I am objecting to deleting it > outright... Ok, fair enough. I've attached a revised version of the patch -- let me know you think it needs further improvements. Neil Conway
-rw-r--r--doc/src/sgml/mvcc.sgml103
1 files changed, 76 insertions, 27 deletions
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml
index fbf6e68432a..2ee64a1d3a6 100644
--- a/doc/src/sgml/mvcc.sgml
+++ b/doc/src/sgml/mvcc.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.30 2002/11/15 03:11:17 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.31 2002/12/18 20:40:24 momjian Exp $
-->
<chapter id="mvcc">
@@ -57,11 +57,10 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.30 2002/11/15 03:11:17 momjia
<title>Transaction Isolation</title>
<para>
- The <acronym>SQL</acronym>
- standard defines four levels of transaction
- isolation in terms of three phenomena that must be prevented
- between concurrent transactions.
- These undesirable phenomena are:
+ The <acronym>SQL</acronym> standard defines four levels of
+ transaction isolation in terms of three phenomena that must be
+ prevented between concurrent transactions. These undesirable
+ phenomena are:
<variablelist>
<varlistentry>
@@ -200,7 +199,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.30 2002/11/15 03:11:17 momjia
<para>
<productname>PostgreSQL</productname>
- offers the read committed and serializable isolation levels.
+ offers the Read Committed and Serializable isolation levels.
</para>
<sect2 id="xact-read-committed">
@@ -635,7 +634,7 @@ ERROR: Can't serialize access due to concurrent update
In addition to table and row locks, page-level share/exclusive locks are
used to control read/write access to table pages in the shared buffer
pool. These locks are released immediately after a tuple is fetched or
- updated. Application writers normally need not be concerned with
+ updated. Application developers normally need not be concerned with
page-level locks, but we mention them for completeness.
</para>
@@ -645,25 +644,70 @@ ERROR: Can't serialize access due to concurrent update
<title>Deadlocks</title>
<para>
- Use of explicit locking can cause <firstterm>deadlocks</>, wherein
- two (or more) transactions each hold locks that the other wants.
- For example, if transaction 1 acquires an exclusive lock on table A
- and then tries to acquire an exclusive lock on table B, while transaction
- 2 has already exclusive-locked table B and now wants an exclusive lock
- on table A, then neither one can proceed.
- <productname>PostgreSQL</productname> automatically detects deadlock
- situations and resolves them by aborting one of the transactions
- involved, allowing the other(s) to complete. (Exactly which transaction
- will be aborted is difficult to predict and should not be relied on.)
+ The use of explicit locking can increase the likelyhood of
+ <firstterm>deadlocks</>, wherein two (or more) transactions each
+ hold locks that the other wants. For example, if transaction 1
+ acquires an exclusive lock on table A and then tries to acquire
+ an exclusive lock on table B, while transaction 2 has already
+ exclusive-locked table B and now wants an exclusive lock on table
+ A, then neither one can proceed.
+ <productname>PostgreSQL</productname> automatically detects
+ deadlock situations and resolves them by aborting one of the
+ transactions involved, allowing the other(s) to complete.
+ (Exactly which transaction will be aborted is difficult to
+ predict and should not be relied on.)
</para>
<para>
- The best defense against deadlocks is generally to avoid them by being
- certain that all applications using a database acquire locks on multiple
- objects in a consistent order. One should also ensure that the first
- lock acquired on an object in a transaction is the highest mode that
- will be needed for that object. If it is not feasible to verify this
- in advance, then deadlocks may be handled on-the-fly by retrying
+ Note that deadlocks can also occur as the result of row-level
+ locks (and thus, they can occur even if explicit locking is not
+ used). Consider the case in which there are two concurrent
+ transactions modifying a table. The first transaction executes:
+
+<screen>
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;
+</screen>
+
+ This acquires a row-level lock on the row with the specified
+ account number. Then, the second transaction executes:
+
+<screen>
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;
+</screen>
+
+ The first <command>UPDATE</command> statement successfully
+ acquires a row-level lock on the specified row, so it succeeds in
+ updating that row. However, the second <command>UPDATE</command>
+ statement finds that the row it is attempting to update has
+ already been locked, so it waits for the transaction that
+ acquired the lock to complete. Transaction two is now waiting on
+ transaction one to complete before it continues execution. Now,
+ transaction one executes:
+
+<screen>
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
+</screen>
+
+ Transaction one attempts to acquire a row-level lock on the
+ specified row, but it cannot: transaction two already holds such
+ a lock. So it waits for transaction two to complete. Thus,
+ transaction one is blocked on transaction two, and transaction
+ two is blocked on transaction one: a deadlock
+ condition. <productname>PostgreSQL</productname> will detect this
+ situation and abort one of the transactions.
+ </para>
+
+ <para>
+ The best defense against deadlocks is generally to avoid them by
+ being certain that all applications using a database acquire
+ locks on multiple objects in a consistent order. That was the
+ reason for the previous deadlock example: if both transactions
+ had updated the rows in the same order, no deadlock would have
+ occurred. One should also ensure that the first lock acquired on
+ an object in a transaction is the highest mode that will be
+ needed for that object. If it is not feasible to verify this in
+ advance, then deadlocks may be handled on-the-fly by retrying
transactions that are aborted due to deadlock.
</para>
@@ -822,9 +866,14 @@ ERROR: Can't serialize access due to concurrent update
</para>
<para>
- In short, B-tree indexes are the recommended index type for concurrent
- applications.
- </para>
+ In short, B-tree indexes offer the best performance for concurrent
+ applications; since they also have more features than hash
+ indexes, they are the recommended index type for concurrent
+ applications that need to index scalar data. When dealing with
+ non-scalar data, B-trees obviously cannot be used; in that
+ situation, application developers should be aware of the
+ relatively poor concurrent performance of GiST and R-tree
+ indexes.
</sect1>
</chapter>