diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml
index 02245c1bfa3..48d462ab299 100644
--- a/doc/src/sgml/ref/lock.sgml
+++ b/doc/src/sgml/ref/lock.sgml
@@ -25,7 +25,7 @@ LOCK [ TABLE ] table IN SHARE ROW E
- 1998-09-01
+ 1999-06-09
Inputs
@@ -46,20 +46,23 @@ LOCK [ TABLE ] table IN SHARE ROW E
- SHARE MODE
+ ACCESS SHARE MODE
+
-
-
-
+ This lock mode is acquired automatically over tables being queried.
+ Postgres releases automatically acquired
+ ACCESS SHARE locks after statement is done.
+
+
-
-
- EXCLUSIVE MODE
-
-
-
+
+ This is the less restrictive lock mode which conflicts with
+ ACCESS EXCLUSIVE mode only. It's intended to protect table being
+ queried from concurrent ALTER TABLE,
+ DROP TABLE and VACUUM
+ statements over the same table.
@@ -69,7 +72,14 @@ LOCK [ TABLE ] table IN SHARE ROW E
ROW SHARE MODE
+
+ Automatically acquired by SELECT FOR UPDATE statement.
+
+
+
+
+ Conflicts with EXCLUSIVE and ACCESS EXCLUSIVE lock modes.
@@ -79,27 +89,36 @@ LOCK [ TABLE ] table IN SHARE ROW E
ROW EXCLUSIVE MODE
+
+ Automatically acquired by UPDATE,
+ DELETE, INSERT statements.
+
+
+
+
+ Conflicts with SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
+ ACCESS EXCLUSIVE modes. Generally means that a transaction
+ updated/inserted some tuples in a table.
- ACCESS SHARE MODE
+ SHARE MODE
+
+ Automatically acquired by CREATE INDEX statement.
-
-
+
-
-
- ACCESS EXCLUSIVE MODE
-
-
-
+
+ Conflicts with ROW EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
+ ACCESS EXCLUSIVE modes. This mode protects a table against
+ concurrent updates.
@@ -109,10 +128,58 @@ LOCK [ TABLE ] table IN SHARE ROW E
SHARE ROW EXCLUSIVE MODE
-
+
+
+ Conflicts with ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
+ EXCLUSIVE and ACCESS EXCLUSIVE modes. This mode is more
+ restrictive than SHARE mode because of only one transaction
+ at time can hold this lock.
+
+
+
+ EXCLUSIVE MODE
+
+
+
+
+ Conflicts with ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
+ EXCLUSIVE and ACCESS EXCLUSIVE modes. This mode is yet more
+ restrictive than SHARE ROW EXCLUSIVE one - it blocks concurrent
+ SELECT FOR UPDATE queries.
+
+
+
+
+
+
+ ACCESS EXCLUSIVE MODE
+
+
+
+
+ Automatically acquired by ALTER TABLE,
+ DROP TABLE, VACUUM statements.
+
+
+
+
+ This is the most restrictive lock mode which conflicts with all other
+ lock modes and protects locked table from any concurrent operations.
+
+
+
+
+ This lock mode is also acquired by first form of
+ LOCK TABLE (i.e. without explicit
+ lock mode option).
+
+
+
+
+
@@ -151,36 +218,73 @@ LOCK [ TABLE ] table IN SHARE ROW E
Description
- By default, LOCK locks in exclusive mode a table inside
- a transaction. Various options allow shared access, or row-level locking
- control. The classic use for this is
- the case where you want to select some data, then
- update it inside a transaction.
- If you don't explicit lock a table using LOCK statement, it will be
- implicit locked only at the first
- UPDATE, INSERT,
- or DELETE operation.
- If you don't exclusive lock the table before the select, some
- other user may also read the selected data, and try and do
- their own update, causing a deadlock while you both wait
- for the other to release the select-induced shared lock so
- you can get an exclusive lock to do the update.
+ Postgres always uses less restrictive
+ lock modes ever possible. LOCK TABLE statement
+ provided for cases when you might need in more restrictive locking.
+
- Another example of deadlock is where one user locks one
- table, and another user locks a second table. While both
- keep their existing locks, the first user tries to lock
- the second user's table, and the second user tries to lock
- the first user's table. Both users deadlock waiting for
- the tables to become available. The only solution to this
- is for both users to lock tables in the same order, so
- user's lock acquisitions and requests to not form a deadlock.
+ For example, application run transaction at READ COMMITTED isolation
+ level and need to ensure existance data in a table for duration of
+ transaction. To achieve this you could use SHARE lock mode over
+ table before querying. This will protect data from concurrent changes
+ and provide your further read operations over table with data in their
+ real current state, because of SHARE lock mode conflicts with ROW EXCLUSIVE
+ one, acquired by writers, and your LOCK TABLE table IN SHARE MODE statement
+ will wait untill concurrent write operations (if any) commit/rollback.
+ (Note that to read data in their real current state running transaction
+ at SERIALIZABLE isolation level you have to execute LOCK TABLE
+ statement before execution any DML statement, when transaction defines
+ what concurrent changes will be visible to herself).
+
+
+ If, in addition to requirements above, transaction is going to
+ change data in a table then SHARE ROW EXCLUSIVE lock mode should
+ be acquired to prevent deadlock conditions when two concurrent
+ transactions would lock table in SHARE mode and than would
+ try to change data in this table, both (implicitly) acquiring
+ ROW EXCLUSIVE lock mode that conflicts with concurrent SHARE lock.
+
+
+
+ Following deadlock issue (when two transaction wait one another)
+ touched above, you should follow two general rules to prevent
+ deadlock conditions:
+
+
+
+
+ Transactions have to acquire locks on the same objects in the same order.
+
+
+
+ For example, if one application updates row R1 and than updates
+ row R2 (in the same transaction) then second application shouldn't
+ update row R2 if it's going update row R1 later (in single transaction).
+ Instead, it should update R1 and R2 rows in the same order as first
+ application.
+
+
+
+
+
+ Transactions should acquire two conflicting lock modes only if
+ one of them is self-conflicting (i.e. may be held by one
+ transaction at time only) and should acquire most restrictive
+ mode first.
+
+
+
+ Example for this rule is described above when told about using
+ SHARE ROW EXCLUSIVE mode instead of SHARE one.
+
+
+
Postgres does detect deadlocks and will
- rollback transactions to resolve the deadlock. Usually, at least one
- of the deadlocked transactions will complete successfully.
+ rollback one of waiting transactions to resolve the deadlock.
@@ -195,16 +299,13 @@ LOCK [ TABLE ] table IN SHARE ROW E
LOCK is a Postgres
language extension.
+
+ Except for ACCESS SHARE/EXCLUSIVE lock modes, all other
+ Postgres lock modes and
+ LOCK TABLE syntax are compatible with
+ Oracle ones.
LOCK works only inside transactions.
-
-
- Bug
-
- If the locked table is dropped then it will be automatically
- unlocked even if a transaction is still in progress.
-
-
@@ -213,18 +314,40 @@ LOCK [ TABLE ] table IN SHARE ROW E
Usage
+
-
- --Explicit locking to prevent deadlock:
+ --
+ -- SHARE lock primary key table when going to perform
+ -- insert into foreign key table.
--
BEGIN WORK;
- LOCK films;
- SELECT * FROM films;
- UPDATE films SET len = INTERVAL '100 minute'
- WHERE len = INTERVAL '117 minute';
+ LOCK TABLE films IN SHARE MODE;
+ SELECT id FROM films
+ WHERE name = 'Star Wars: Episode I - The Phantom Menace';
+ --
+ -- Do ROLLBACK if record was not returned
+ --
+ INSERT INTO films_user_comments VALUES
+ (_id_, 'GREAT! I was waiting it so long!');
COMMIT WORK;
+
+
+
+
+ --
+ -- SHARE ROW EXCLUSIVE lock primary key table when going to perform
+ -- delete operation.
+ --
+ BEGIN WORK;
+ LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
+ DELETE FROM films_user_comments WHERE id IN
+ (SELECT id FROM films WHERE rating < 5);
+ DELETE FROM films WHERE rating < 5;
+ COMMIT WORK;
+
+
diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml
index e44e4c273a4..3014bbda502 100644
--- a/doc/src/sgml/ref/set.sgml
+++ b/doc/src/sgml/ref/set.sgml
@@ -20,7 +20,7 @@
SET variable { TO | = } { 'value' | DEFAULT }
SET TIME ZONE { 'timezone' | LOCAL | DEFAULT };
-SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT }
+SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED }
@@ -350,9 +350,16 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT }
- The current transaction reads only
- committed rows. READ COMMITTED is the default.
+ The current transaction queries read only rows committed
+ before a query began. READ COMMITTED is the default.
+
+
+
+ SQL92 standard requires
+ SERIALIZABLE to be the default isolation level.
+
+
@@ -362,24 +369,14 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT }
- The current transaction will place a
- lock on every row read, so later reads in that transaction
- see the rows unmodified by other transactions.
+ The current transaction queries read only rows committed
+ before first DML statement
+ (SELECT/INSERT/DELETE/UPDATE/FETCH/COPY_TO)
+ was executed in this transaction.
-
-
- DEFAULT
-
-
-
- Sets the isolation level for the current transaction to
- .
-
-
-
@@ -789,7 +786,7 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT }
There is no
SET variable
- in SQL92.
+ in SQL92 (except for SET TRANSACTION ISOLATION LEVEL).
The SQL92 syntax for SET TIME ZONE
is slightly different,