Tweak row-level locking documentation
authorAlvaro Herrera
Thu, 13 Nov 2014 17:45:55 +0000 (14:45 -0300)
committerAlvaro Herrera
Thu, 13 Nov 2014 17:45:55 +0000 (14:45 -0300)
Move the meat of locking levels to mvcc.sgml, leaving only a link to it
in the SELECT reference page.

Michael Paquier, with some tweaks by Álvaro

doc/src/sgml/mvcc.sgml
doc/src/sgml/ref/select.sgml

index cd55be8a6b4e5de251968739d2dde3e3caa487d5..a0d6867de0f12ebf51f03e03661e3d2cd206d674 100644 (file)
@@ -1106,30 +1106,108 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 
     
      In addition to table-level locks, there are row-level locks, which
-     can be exclusive or shared locks.  An exclusive row-level lock on a
-     specific row is automatically acquired when the row is updated or
-     deleted.  The lock is held until the transaction commits or rolls
-     back, just like table-level locks.  Row-level locks do
-     not affect data querying; they block only writers to the same
-     row.
+     are listed as below with the contexts in which they are used
+     automatically by PostgreSQL.  See
+      for a complete table of
+     row-level lock conflicts.  Note that a transaction can hold
+     conflicting locks on the same row, even in different subtransactions;
+     but other than that, two transactions can never hold conflicting locks
+     on the same row.  Row-level locks do not affect data querying; they
+     block only writers and lockers to the same row.
     
 
-    
-     To acquire an exclusive row-level lock on a row without actually
-     modifying the row, select the row with SELECT FOR
-     UPDATE.  Note that once the row-level lock is acquired,
-     the transaction can update the row multiple times without
-     fear of conflicts.
-    
+     
+      Row-level Lock Modes
+      
+       
+        FOR UPDATE
+       
+       
+        
+         FOR UPDATE causes the rows retrieved by the
+         SELECT statement to be locked as though for
+         update.  This prevents them from being locked, modified or deleted by
+         other transactions until the current transaction ends.  That is,
+         other transactions that attempt UPDATE,
+         DELETE,
+         SELECT FOR UPDATE,
+         SELECT FOR NO KEY UPDATE,
+         SELECT FOR SHARE or
+         SELECT FOR KEY SHARE
+         of these rows will be blocked until the current transaction ends;
+         conversely, SELECT FOR UPDATE will wait for a
+         concurrent transaction that has run any of those commands on the
+         same row,
+         and will then lock and return the updated row (or no row, if the
+         row was deleted).  Within a REPEATABLE READ or
+         SERIALIZABLE transaction,
+         however, an error will be thrown if a row to be locked has changed
+         since the transaction started.  For further discussion see
+         .
+        
+        
+         The FOR UPDATE lock mode
+         is also acquired by any DELETE on a row, and also by an
+         UPDATE that modifies the values on certain columns.  Currently,
+         the set of columns considered for the UPDATE case are those that
+         have a unique index on them that can be used in a foreign key (so partial
+         indexes and expressional indexes are not considered), but this may change
+         in the future.
+        
+       
+      
 
-    
-     To acquire a shared row-level lock on a row, select the row with
-     SELECT FOR SHARE.  A shared lock does not prevent
-     other transactions from acquiring the same shared lock.  However,
-     no transaction is allowed to update, delete, or exclusively lock a
-     row on which any other transaction holds a shared lock.  Any attempt
-     to do so will block until the shared lock(s) have been released.
-    
+      
+       
+        FOR NO KEY UPDATE
+       
+       
+        
+         Behaves similarly to FOR UPDATE, except that the lock
+         acquired is weaker: this lock will not block
+         SELECT FOR KEY SHARE commands that attempt to acquire
+         a lock on the same rows. This lock mode is also acquired by any
+         UPDATE that does not acquire a FOR UPDATE lock.
+        
+       
+      
+
+      
+       
+        FOR SHARE
+       
+       
+        
+         Behaves similarly to FOR NO KEY UPDATE, except that it
+         acquires a shared lock rather than exclusive lock on each retrieved
+         row.  A shared lock blocks other transactions from performing
+         UPDATEDELETE,
+         SELECT FOR UPDATE or
+         SELECT FOR NO KEY UPDATE on these rows, but it does not
+         prevent them from performing SELECT FOR SHARE or
+         SELECT FOR KEY SHARE.
+        
+       
+      
+
+      
+       
+        FOR KEY SHARE
+       
+       
+        
+         Behaves similarly to FOR SHARE, except that the
+         lock is weaker: SELECT FOR UPDATE is blocked, but not
+         SELECT FOR NO KEY UPDATE.  A key-shared lock blocks
+         other transactions from performing DELETE or
+         any UPDATE that changes the key values, but not
+         other UPDATE, and neither does it prevent
+         SELECT FOR NO KEY UPDATE, SELECT FOR SHARE,
+         or SELECT FOR KEY SHARE.
+        
+       
+      
+     
 
     
      PostgreSQL doesn't remember any
@@ -1139,11 +1217,62 @@ ERROR:  could not serialize access due to read/write dependencies among transact
      UPDATE modifies selected rows to mark them locked, and so
      will result in disk writes.
     
+
+    
+     Conflicting Row-level Locks
+     
+      
+      
+      
+      
+       
+        Requested Lock Mode
+        Current Lock Mode
+       
+       
+        FOR KEY SHARE
+        FOR SHARE
+        FOR NO KEY UPDATE
+        FOR UPDATE
+       
+      
+      
+       
+        FOR KEY SHARE
+        
+        
+        
+        X
+       
+       
+        FOR SHARE
+        
+        
+        X
+        X
+       
+       
+        FOR NO KEY UPDATE
+        
+        X
+        X
+        X
+       
+       
+        FOR UPDATE
+        X
+        X
+        X
+        X
+       
+      
+     
+    
    
 
    
     Page-level Locks
-  
+
     
      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
index 473939ab4eb1c1db9d055365f6f7914565fd5652..3e5a2f5092d56ce03a4c6446759c6f9c58b35530 100644 (file)
@@ -1298,64 +1298,8 @@ KEY SHARE
    
 
    
-    FOR UPDATE causes the rows retrieved by the
-    SELECT statement to be locked as though for
-    update.  This prevents them from being modified or deleted by
-    other transactions until the current transaction ends.  That is,
-    other transactions that attempt UPDATE,
-    DELETE,
-    SELECT FOR UPDATE,
-    SELECT FOR NO KEY UPDATE,
-    SELECT FOR SHARE or
-    SELECT FOR KEY SHARE
-    of these rows will be blocked until the current transaction ends.
-    The FOR UPDATE lock mode
-    is also acquired by any DELETE on a row, and also by an
-    UPDATE that modifies the values on certain columns.  Currently,
-    the set of columns considered for the UPDATE case are those that
-    have a unique index on them that can be used in a foreign key (so partial
-    indexes and expressional indexes are not considered), but this may change
-    in the future.
-    Also, if an UPDATEDELETE,
-    or SELECT FOR UPDATE from another transaction
-    has already locked a selected row or rows, SELECT FOR
-    UPDATE will wait for the other transaction to complete,
-    and will then lock and return the updated row (or no row, if the
-    row was deleted).  Within a REPEATABLE READ or SERIALIZABLE transaction,
-    however, an error will be thrown if a row to be locked has changed
-    since the transaction started.  For further discussion see 
-    linkend="mvcc">.
-   
-
-   
-    FOR NO KEY UPDATE behaves similarly, except that the lock
-    acquired is weaker: this lock will not block
-    SELECT FOR KEY SHARE commands that attempt to acquire
-    a lock on the same rows. This lock mode is also acquired by any
-    UPDATE that does not acquire a FOR UPDATE lock.
-   
-
-   
-    FOR SHARE behaves similarly, except that it
-    acquires a shared rather than exclusive lock on each retrieved
-    row.  A shared lock blocks other transactions from performing
-    UPDATEDELETESELECT
-    FOR UPDATE or SELECT FOR NO KEY UPDATE
-    on these rows, but it does not prevent them
-    from performing SELECT FOR SHARE or
-    SELECT FOR KEY SHARE.
-   
-
-   
-    FOR KEY SHARE behaves similarly to FOR SHARE,
-    except that the lock
-    is weaker: SELECT FOR UPDATE is blocked, but
-    not SELECT FOR NO KEY UPDATE.  A key-shared
-    lock blocks other transactions from performing DELETE
-    or any UPDATE that changes the key values, but not
-    other UPDATE, and neither does it prevent
-    SELECT FOR NO KEY UPDATE, SELECT FOR SHARE, or
-    SELECT FOR KEY SHARE.
+    For more information on each row-level lock mode, refer to
+    .