Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
606db06f
Commit
606db06f
authored
May 30, 2002
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve manual's discussion of locking and MVCC.
parent
3dd13ffd
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
497 additions
and
299 deletions
+497
-299
doc/src/sgml/mvcc.sgml
doc/src/sgml/mvcc.sgml
+330
-154
doc/src/sgml/ref/lock.sgml
doc/src/sgml/ref/lock.sgml
+167
-145
No files found.
doc/src/sgml/mvcc.sgml
View file @
606db06f
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.2
4 2002/03/27 02:36:51 petere
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.2
5 2002/05/30 20:45:18 tgl
Exp $
-->
-->
<chapter id="mvcc">
<chapter id="mvcc">
...
@@ -43,6 +43,13 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
...
@@ -43,6 +43,13 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
with locks acquired for writing data, and so reading never blocks
with locks acquired for writing data, and so reading never blocks
writing and writing never blocks reading.
writing and writing never blocks reading.
</para>
</para>
<para>
Table- and row-level locking facilities are also available in
<productname>PostgreSQL</productname> for applications that cannot
adapt easily to MVCC behavior. However, proper use of MVCC will
generally provide better performance than locks.
</para>
</sect1>
</sect1>
<sect1 id="transaction-iso">
<sect1 id="transaction-iso">
...
@@ -63,7 +70,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
...
@@ -63,7 +70,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
</term>
</term>
<listitem>
<listitem>
<para>
<para>
A transaction reads data written by concurrent uncommitted transaction.
A transaction reads data written by
a
concurrent uncommitted transaction.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -209,41 +216,76 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
...
@@ -209,41 +216,76 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
is the default isolation level in <productname>PostgreSQL</productname>.
is the default isolation level in <productname>PostgreSQL</productname>.
When a transaction runs on this isolation level,
When a transaction runs on this isolation level,
a <command>SELECT</command> query sees only data committed before the
a <command>SELECT</command> query sees only data committed before the
query began
and
never sees either uncommitted data or changes committed
query began
; it
never sees either uncommitted data or changes committed
during query execution by concurrent transactions. (However, the
during query execution by concurrent transactions. (However, the
<command>SELECT</command> does see the effects of previous updates
<command>SELECT</command> does see the effects of previous updates
executed within this same transaction, even though they are not yet
executed within its own transaction, even though they are not yet
committed.) Notice that two successive <command>SELECT</command>s can see different data,
committed.) In effect, a <command>SELECT</command> query
even though they are within a single transaction, when other transactions
sees a snapshot of the database as of the instant that that query
begins to run. Notice that two successive <command>SELECT</command>s can
see different data, even 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>
<para>
<para>
If a target row found by a query while executing an
<command>UPDATE</command>, <command>DELETE</command> and <command>SELECT
<command>UPDATE</command> statement
FOR UPDATE</command> commands behave the same as <command>SELECT</command>
(or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
in terms of searching for target rows: they will only find target rows
has already been updated by a
that were committed as of the query start time. However, such a target
concurrent uncommitted transaction then the second transaction
row may have already been updated (or deleted or marked for update) by
that tries to update this row will wait for the other transaction to
another concurrent transaction by the time it is found. In this case, the
commit or rollback. In the case of rollback, the waiting transaction
would-be updater will wait for the first updating transaction to commit or
can proceed to change the row. In the case of commit (and if the
roll back (if it is still in progress). If the first updater rolls back,
row still exists; i.e. was not deleted by the other transaction), the
then its effects are negated and the second updater can proceed with
query will be re-executed for this row to check that the new row
updating the originally found row. If the first updater commits, the
version still satisfies the query search condition. If the new row version
second updater will ignore the row if the first updater deleted it,
satisfies the query search condition then the row will be
otherwise it will attempt to apply its operation to the updated version of
updated (or deleted or marked for update). Note that the starting point
the row. The query search condition (<literal>WHERE</> clause) is
for the update will be the new row version; moreover, after the update
re-evaluated to see if the updated version of the row still matches the
the doubly-updated row is visible to subsequent <command>SELECT</command>s
search condition. If so, the second updater proceeds with its operation,
in the current transaction. Thus, the current transaction is able to see
starting from the updated version of the row.
the effects of the other transaction for this specific row.
</para>
<para>
Because of the above rule, it is possible for updating queries to see
inconsistent snapshots --- they can see the effects of concurrent updating
queries that affected the same rows they are trying to update, but they
do not see effects of those queries on other rows in the database.
This behavior makes Read Committed mode unsuitable for queries that
involve complex search conditions. However, it is just right for simpler
cases. For example, consider updating bank balances with transactions
like
<screen>
BEGIN;
UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 12345;
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534;
COMMIT;
</screen>
If two such transactions concurrently try to change the balance of account
12345, we clearly want the second transaction to start from the updated
version of the account's row. Because each query is affecting only a
predetermined row, letting it see the updated version of the row does
not create any troublesome inconsistency.
</para>
</para>
<para>
<para>
The partial transaction isolation provided by Read Committed level is
Since in Read Committed mode each new query starts with a new snapshot
adequate for many applications, and this level is fast and simple to use.
that includes all transactions committed up to that instant, subsequent
queries in the same transaction will see the effects of the committed
concurrent transaction in any case. The point at issue here is whether
or not within a <emphasis>single</> query we see 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, for applications that do complex queries and updates, it may
However, for applications that do complex queries and updates, it may
be necessary to guarantee a more rigorously consistent view of the
be necessary to guarantee a more rigorously consistent view of the
database than the Read Committed
level
provides.
database than the Read Committed
mode
provides.
</para>
</para>
</sect1>
</sect1>
...
@@ -256,7 +298,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
...
@@ -256,7 +298,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
</indexterm>
</indexterm>
<para>
<para>
<firstterm>Serializable</firstterm> provides the
high
est transaction
<firstterm>Serializable</firstterm> provides the
strict
est transaction
isolation. This level emulates serial transaction execution,
isolation. This level emulates serial transaction execution,
as if transactions had been executed one after another, serially,
as if transactions had been executed one after another, serially,
rather than concurrently. However, applications using this level must
rather than concurrently. However, applications using this level must
...
@@ -266,28 +308,33 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
...
@@ -266,28 +308,33 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.24 2002/03/27 02:36:51 petere
<para>
<para>
When a transaction is on the serializable level,
When a transaction is on the serializable level,
a <command>SELECT</command> query sees only data committed before the
a <command>SELECT</command> query sees only data committed before the
transaction began
and
never sees either uncommitted data or changes
transaction began
; it
never sees either uncommitted data or changes
committed
committed
during transaction execution by concurrent transactions. (However, the
during transaction execution by concurrent transactions. (However, the
<command>SELECT</command> does see the effects of previous updates
<command>SELECT</command> does see the effects of previous updates
executed within
this same
transaction, even though they are not yet
executed within
its own
transaction, even though they are not yet
committed.) This is different from Read Committed in that the
committed.) This is different from Read Committed in that the
<command>SELECT</command>
<command>SELECT</command>
sees a snapshot as of the start of the transaction, not as of the start
sees a snapshot as of the start of the transaction, not as of the start
of the current query within the transaction.
of the current query within the transaction. Successive
</para>
<command>SELECT</command>s within a single transaction always see the same
data.
<para>
</para>
If a target row found by a query while executing an
<command>UPDATE</command> statement
<para>
(or <command>DELETE</command> or <command>SELECT FOR UPDATE</command>)
<command>UPDATE</command>, <command>DELETE</command> and <command>SELECT
has already been updated by a
FOR UPDATE</command> commands behave the same as <command>SELECT</command>
concurrent uncommitted transaction then the second transaction
in terms of searching for target rows: they will only find target rows
that tries to update this row will wait for the other transaction to
that were committed as of the transaction start time. However, such a
commit or rollback. In the case of rollback, the waiting transaction
target
can proceed to change the row. In the case of a concurrent
row may have already been updated (or deleted or marked for update) by
transaction commit, a serializable transaction will be rolled back
another concurrent transaction by the time it is found. In this case, the
with the message
serializable transaction will wait for the first updating transaction to commit or
roll back (if it is still in progress). If the first updater rolls back,
then its effects are negated and the serializable transaction can proceed
with updating the originally found row. But if the first updater commits
(and actually updated or deleted the row, not just selected it for update)
then the serializable transaction will be rolled back with the message
<screen>
<screen>
ERROR: Can't serialize access due to concurrent update
ERROR: Can't serialize access due to concurrent update
...
@@ -304,72 +351,29 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -304,72 +351,29 @@ ERROR: Can't serialize access due to concurrent update
previously-committed change as part of its initial view of the database,
previously-committed change as part of its initial view of the database,
so there is no logical conflict in using the new version of the row
so there is no logical conflict in using the new version of the row
as the starting point for the new transaction's update.
as the starting point for the new transaction's update.
Note that only updating transactions may need to be retried --- read-only
transactions never have serialization conflicts.
</para>
</para>
<para>
<para>
The Serializable transaction level provides a rigorous guarantee that each
Note that only updating transactions may need to be retried --- read-only
transaction sees a wholly consistent view of the database. However,
transactions will never have serialization conflicts.
the application has to be prepared to retry transactions when concurrent
updates make it impossible to sustain the illusion of serial execution,
and the cost of redoing complex transactions may be significant. So
this level is recommended only when update queries contain logic
sufficiently complex that they may give wrong answers in the Read Committed
level.
</para>
</sect1>
<sect1 id="applevel-consistency">
<title>Data consistency checks at the application level</title>
<para>
Because readers in <productname>PostgreSQL</productname>
don't lock data, regardless of
transaction isolation level, data read by one transaction can be
overwritten by another concurrent transaction. In other words,
if a row is returned by <command>SELECT</command> it doesn't mean that
the row still exists at the time it is returned (i.e., sometime after the
current transaction began); the row might have been modified or deleted
by an already-committed transaction that committed after this one started.
Even if the row is still valid <quote>now</quote>, it could be changed or deleted
before the current transaction does a commit or rollback.
</para>
<para>
Another way to think about it is that each
transaction sees a snapshot of the database contents, and concurrently
executing transactions may very well see different snapshots. So the
whole concept of <quote>now</quote> is somewhat suspect anyway. This is not normally
a big problem if the client applications are isolated from each other,
but if the clients can communicate via channels outside the database
then serious confusion may ensue.
</para>
</para>
<para>
<para>
To ensure the current existence of a row and protect it against
The Serializable mode provides a rigorous guarantee that each
concurrent updates one must use <command>SELECT FOR UPDATE</command> or
transaction sees a wholly consistent view of the database. However,
an appropriate <command>LOCK TABLE</command> statement.
the application has to be prepared to retry transactions when concurrent
(<command>SELECT FOR UPDATE</command> locks just the returned rows against
updates make it impossible to sustain the illusion of serial execution.
concurrent updates, while <command>LOCK TABLE</command> protects the
Since the cost of redoing complex transactions may be significant,
whole table.)
this mode is recommended only when updating transactions contain logic
This should be taken into account when porting applications to
sufficiently complex that they may give wrong answers in Read
<productname>PostgreSQL</productname> from other environments.
Committed mode. Most commonly, Serializable mode is necessary when
a transaction performs several successive queries that must see
<note>
identical views of the database.
<para>
Before version 6.5 <productname>PostgreSQL</productname>
used read-locks and so the
above consideration is also the case
when upgrading to 6.5 (or higher) from previous
<productname>PostgreSQL</productname> versions.
</para>
</note>
</para>
</para>
</sect1>
</sect1>
<sect1 id="
locking-tables
">
<sect1 id="
explicit-locking
">
<title>
Locking and Tables
</title>
<title>
Explicit Locking
</title>
<indexterm>
<indexterm>
<primary>locking</primary>
<primary>locking</primary>
...
@@ -377,20 +381,40 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -377,20 +381,40 @@ ERROR: Can't serialize access due to concurrent update
<para>
<para>
<productname>PostgreSQL</productname> provides various lock modes
<productname>PostgreSQL</productname> provides various lock modes
to control concurrent access to data in tables. Users normally
to control concurrent access to data in tables. These modes can be
need not be concerned about the different lock modes because
used for application-controlled locking in situations where MVCC
does not give the desired behavior. Also, most
<productname>PostgreSQL</productname> commands automatically
<productname>PostgreSQL</productname> commands automatically
acquire locks of appropriate modes to ensure
data integrity while
acquire locks of appropriate modes to ensure
that referenced tables
permitting an appropriate level of concurrent access.
are not dropped or modified in incompatible ways while the command
Nevertheless, a user can manually lock a table in any of the
executes. (For example, <command>ALTER TABLE</> cannot be executed
available modes using the <command>LOCK TABLE</command> command.
concurrently with other operations on the same table.)
</para>
</para>
<sect2 id="locking-tables">
<title>Table-Level Locks</title>
<para>
<para>
The list below shows the available lock modes and the contexts in
The list below shows the available lock modes and the contexts in
which they are used. Remember that all of these lock modes are
which they are used automatically by
table-level locks, even if the name contains the word
<productname>PostgreSQL</productname>.
Remember that all of these lock modes are table-level locks,
even if the name contains the word
<quote>row</quote>. The names of the lock modes are historical.
<quote>row</quote>. The names of the lock modes are historical.
To some extent the names reflect the typical usage of each lock
mode --- but the semantics are all the same. The only real difference
between one lock mode and another is the set of lock modes with
which each conflicts. Two transactions cannot hold locks of conflicting
modes on the same table at the same time. (However, a transaction
never conflicts with itself --- for example, it may acquire
<literal>ACCESS EXCLUSIVE</literal> lock and later acquire
<literal>ACCESS SHARE</literal> lock on the same table.) Nonconflicting
lock modes may be held concurrently by many transactions. Notice in
particular that some lock modes are self-conflicting (for example,
<literal>ACCESS EXCLUSIVE</literal> cannot be held by more than one
transaction at a time) while others are not self-conflicting (for example,
<literal>ACCESS SHARE</literal> can be held by multiple transactions).
Once acquired, a lock mode is held till end of transaction.
</para>
</para>
<variablelist>
<variablelist>
...
@@ -401,13 +425,15 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -401,13 +425,15 @@ ERROR: Can't serialize access due to concurrent update
</term>
</term>
<listitem>
<listitem>
<para>
<para>
A read-lock mode acquired automatically on tables
Conflicts with the <literal>ACCESS EXCLUSIVE</literal> lock
being queried
.
mode only
.
</para>
</para>
<para>
<para>
Conflicts with the <literal>ACCESS EXCLUSIVE</literal> lock
The <command>SELECT</command> command acquires a
mode only.
lock of this mode on referenced tables. In general, any query
that only reads a table and does not modify it will acquire
this lock mode.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -418,13 +444,15 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -418,13 +444,15 @@ ERROR: Can't serialize access due to concurrent update
</term>
</term>
<listitem>
<listitem>
<para>
<para>
The <command>SELECT FOR UPDATE</command> command acquires a
Conflicts with the <literal>EXCLUSIVE</literal> and
lock of this mode
.
<literal>ACCESS EXCLUSIVE</literal> lock modes
.
</para>
</para>
<para>
<para>
Conflicts with the <literal>EXCLUSIVE</literal> and
The <command>SELECT FOR UPDATE</command> command acquires a
<literal>ACCESS EXCLUSIVE</literal> lock modes.
lock of this mode on the target table(s) (in addition to
<literal>ACCESS SHARE</literal> locks on any other tables
that are referenced but not selected <option>FOR UPDATE</option>).
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -434,17 +462,20 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -434,17 +462,20 @@ ERROR: Can't serialize access due to concurrent update
<literal>ROW EXCLUSIVE</literal>
<literal>ROW EXCLUSIVE</literal>
</term>
</term>
<listitem>
<listitem>
<para>
The commands <command>UPDATE</command>,
<command>DELETE</command>, and <command>INSERT</command>
automatically acquire this lock mode.
</para>
<para>
<para>
Conflicts with the <literal>SHARE</literal>, <literal>SHARE ROW
Conflicts with the <literal>SHARE</literal>, <literal>SHARE ROW
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
<literal>ACCESS EXCLUSIVE</literal> lock modes.
</para>
</para>
<para>
The commands <command>UPDATE</command>,
<command>DELETE</command>, and <command>INSERT</command>
acquire this lock mode on the target table (in addition to
<literal>ACCESS SHARE</literal> locks on any other referenced
tables). In general, this lock mode will be acquired by any
query that modifies the data in a table.
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -453,15 +484,17 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -453,15 +484,17 @@ ERROR: Can't serialize access due to concurrent update
<literal>SHARE UPDATE EXCLUSIVE</literal>
<literal>SHARE UPDATE EXCLUSIVE</literal>
</term>
</term>
<listitem>
<listitem>
<para>
Acquired by <command>VACUUM</command> (without <option>FULL</option>).
</para>
<para>
<para>
Conflicts with the <literal>SHARE UPDATE EXCLUSIVE</literal>,
Conflicts with the <literal>SHARE UPDATE EXCLUSIVE</literal>,
<literal>SHARE</literal>, <literal>SHARE ROW
<literal>SHARE</literal>, <literal>SHARE ROW
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
<literal>ACCESS EXCLUSIVE</literal> lock modes.
This mode protects a table against
concurrent schema changes and VACUUMs.
</para>
<para>
Acquired by <command>VACUUM</command> (without <option>FULL</option>).
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -471,15 +504,16 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -471,15 +504,16 @@ ERROR: Can't serialize access due to concurrent update
<literal>SHARE</literal>
<literal>SHARE</literal>
</term>
</term>
<listitem>
<listitem>
<para>
Acquired by <command>CREATE INDEX</command>.
</para>
<para>
<para>
Conflicts with the <literal>ROW EXCLUSIVE</literal>,
Conflicts with the <literal>ROW EXCLUSIVE</literal>,
<literal>SHARE UPDATE EXCLUSIVE</literal>, <literal>SHARE ROW
<literal>SHARE UPDATE EXCLUSIVE</literal>, <literal>SHARE ROW
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
<literal>ACCESS EXCLUSIVE</literal> lock modes.
This mode protects a table against concurrent data changes.
</para>
<para>
Acquired by <command>CREATE INDEX</command>.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -489,10 +523,6 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -489,10 +523,6 @@ ERROR: Can't serialize access due to concurrent update
<literal>SHARE ROW EXCLUSIVE</literal>
<literal>SHARE ROW EXCLUSIVE</literal>
</term>
</term>
<listitem>
<listitem>
<para>
This lock mode is not automatically acquired by any command.
</para>
<para>
<para>
Conflicts with the <literal>ROW EXCLUSIVE</literal>,
Conflicts with the <literal>ROW EXCLUSIVE</literal>,
<literal>SHARE UPDATE EXCLUSIVE</literal>,
<literal>SHARE UPDATE EXCLUSIVE</literal>,
...
@@ -500,24 +530,33 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -500,24 +530,33 @@ ERROR: Can't serialize access due to concurrent update
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
<literal>ACCESS EXCLUSIVE</literal> lock modes.
</para>
</para>
<para>
This lock mode is not automatically acquired by any
<productname>PostgreSQL</productname> command.
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>
<term>
<literal>EXCLUSIVE
LOCK
</literal>
<literal>EXCLUSIVE</literal>
</term>
</term>
<listitem>
<listitem>
<para>
This lock mode is not automatically acquired by any command.
</para>
<para>
<para>
Conflicts with the <literal>ROW SHARE</literal>, <literal>ROW
Conflicts with the <literal>ROW SHARE</literal>, <literal>ROW
EXCLUSIVE</literal>, <literal>SHARE UPDATE
EXCLUSIVE</literal>, <literal>SHARE UPDATE
EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal> lock modes.
<literal>ACCESS EXCLUSIVE</literal> lock modes.
This mode allows only concurrent <literal>ACCESS SHARE</literal>,
i.e., only reads from the table can proceed in parallel with a
transaction holding this lock mode.
</para>
<para>
This lock mode is not automatically acquired by any
<productname>PostgreSQL</productname> command.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -528,19 +567,21 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -528,19 +567,21 @@ ERROR: Can't serialize access due to concurrent update
</term>
</term>
<listitem>
<listitem>
<para>
<para>
Acquired by the <command>ALTER TABLE</command>, <command>DROP
Conflicts with locks of all modes (<literal>ACCESS
TABLE</command>, and <command>VACUUM FULL</command> commands.
This is also the default lock mode for <command>LOCK TABLE</command>
statements that do not specify a mode explicitly.
</para>
<para>
Conflicts with locks of all modes ( <literal>ACCESS
SHARE</literal>, <literal>ROW SHARE</literal>, <literal>ROW
SHARE</literal>, <literal>ROW SHARE</literal>, <literal>ROW
EXCLUSIVE</literal>, <literal>SHARE UPDATE
EXCLUSIVE</literal>, <literal>SHARE UPDATE
EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
<literal>ACCESS EXCLUSIVE</literal>).
<literal>ACCESS EXCLUSIVE</literal>).
This mode guarantees that the
holder is the only transaction accessing the table in any way.
</para>
<para>
Acquired by the <command>ALTER TABLE</command>, <command>DROP
TABLE</command>, and <command>VACUUM FULL</command> commands.
This is also the default lock mode for <command>LOCK TABLE</command>
statements that do not specify a mode explicitly.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -554,17 +595,28 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -554,17 +595,28 @@ ERROR: Can't serialize access due to concurrent update
</para>
</para>
</note>
</note>
</sect2>
<sect2 id="locking-rows">
<title>Row-Level Locks</title>
<para>
<para>
In addition to table-level locks, there are row-level locks.
In addition to table-level locks, there are row-level locks.
Row-level locks are acquired when rows are being updated (or
A row-level lock on a specific row is automatically acquired when the
deleted or marked for update). Row-level locks don't affect data
row is updated (or deleted or marked for update). The lock is held
querying; they block writers to <emphasis>the same row</emphasis>
until the transaction commits or rolls back.
only. Row-level locks cannot be acquired explicitly by the user.
Row-level locks don't affect data
querying; they block <emphasis>writers to the same row</emphasis>
only. To acquire a row-level lock on a row without actually
modifying the row, select the row with <command>SELECT FOR
UPDATE</command>. Note that once a particular row-level lock is
acquired, the transaction may update the row multiple times without
fear of conflicts.
</para>
</para>
<para>
<para>
<productname>PostgreSQL</productname> doesn't remember any
<productname>PostgreSQL</productname> doesn't remember any
information about modified rows in memory, so i
s
has no limit to
information about modified rows in memory, so i
t
has no limit to
the number of rows locked at one time. However, locking a row
the number of rows locked at one time. However, locking a row
may cause a disk write; thus, for example, <command>SELECT FOR
may cause a disk write; thus, for example, <command>SELECT FOR
UPDATE</command> will modify selected rows to mark them and so
UPDATE</command> will modify selected rows to mark them and so
...
@@ -572,12 +624,136 @@ ERROR: Can't serialize access due to concurrent update
...
@@ -572,12 +624,136 @@ ERROR: Can't serialize access due to concurrent update
</para>
</para>
<para>
<para>
In addition to table and row locks, short-term
share/exclusive locks are
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
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
pool. These locks are released immediately after a tuple is fetched or
updated. Application writers normally need not be concerned with
updated. Application writers normally need not be concerned with
page-level locks, but we mention them for completeness.
page-level locks, but we mention them for completeness.
</para>
</para>
</sect2>
<sect2 id="locking-deadlocks">
<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 exclusive lock on table A
and then tries to acquire exclusive lock on table B, while transaction
2 has already exclusive-locked table B and now wants 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
transactions that are aborted due to deadlock.
</para>
<para>
So long as no deadlock situation is detected, a transaction seeking
either a table-level or row-level lock will wait indefinitely for
conflicting locks to be released. This means it is a bad idea for
applications to hold transactions open for long periods of time
(e.g., while waiting for user input).
</para>
</sect2>
</sect1>
<sect1 id="applevel-consistency">
<title>Data consistency checks at the application level</title>
<para>
Because readers in <productname>PostgreSQL</productname>
don't lock data, regardless of
transaction isolation level, data read by one transaction can be
overwritten by another concurrent transaction. In other words,
if a row is returned by <command>SELECT</command> it doesn't mean that
the row is still current at the instant it is returned (i.e., sometime
after the current query began). The row might have been modified or
deleted by an already-committed transaction that committed after this one
started.
Even if the row is still valid <quote>now</quote>, it could be changed or
deleted
before the current transaction does a commit or rollback.
</para>
<para>
Another way to think about it is that each
transaction sees a snapshot of the database contents, and concurrently
executing transactions may very well see different snapshots. So the
whole concept of <quote>now</quote> is somewhat suspect anyway.
This is not normally
a big problem if the client applications are isolated from each other,
but if the clients can communicate via channels outside the database
then serious confusion may ensue.
</para>
<para>
To ensure the current validity of a row and protect it against
concurrent updates one must use <command>SELECT FOR UPDATE</command> or
an appropriate <command>LOCK TABLE</command> statement.
(<command>SELECT FOR UPDATE</command> locks just the returned rows against
concurrent updates, while <command>LOCK TABLE</command> locks the
whole table.)
This should be taken into account when porting applications to
<productname>PostgreSQL</productname> from other environments.
<note>
<para>
Before version 6.5 <productname>PostgreSQL</productname>
used read-locks and so the
above consideration is also the case
when upgrading to 6.5 (or higher) from previous
<productname>PostgreSQL</productname> versions.
</para>
</note>
</para>
<para>
Global validity checks require extra thought under MVCC. For
example, a banking application might wish to check that the sum of
all credits in one table equals the sum of debits in another table,
when both tables are being actively updated. Comparing the results of two
successive SELECT SUM(...) commands will not work reliably under
Read Committed mode, since the second query will likely include the results
of transactions not counted by the first. Doing the two sums in a
single serializable transaction will give an accurate picture of the
effects of transactions that committed before the serializable transaction
started --- but one might legitimately wonder whether the answer is still
relevant by the time it is delivered. If the serializable transaction
itself applied some changes before trying to make the consistency check,
the usefulness of the check becomes even more debatable, since now it
includes some but not all post-transaction-start changes. In such cases
a careful person might wish to lock all tables needed for the check,
in order to get an indisputable picture of current reality. A
<literal>SHARE</> mode (or higher) lock guarantees that there are no
uncommitted changes in the locked table, other than those of the current
transaction.
</para>
<para>
Note also that if one is
relying on explicit locks to prevent concurrent changes, one should use
Read Committed mode, or in Serializable mode be careful to obtain the
lock(s) before performing queries. An explicit lock obtained in a
serializable transaction guarantees that no other transactions modifying
the table are still running --- but if the snapshot seen by the
transaction predates obtaining the lock, it may predate some now-committed
changes in the table. A serializable transaction's snapshot is actually
frozen at the start of its first query (SELECT/INSERT/UPDATE/DELETE), so
it's possible to obtain explicit locks before the snapshot is
frozen.
</para>
</sect1>
</sect1>
<sect1 id="locking-indexes">
<sect1 id="locking-indexes">
...
...
doc/src/sgml/ref/lock.sgml
View file @
606db06f
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.3
2 2002/04/23 02:07:16
tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.3
3 2002/05/30 20:45:18
tgl Exp $
PostgreSQL documentation
PostgreSQL documentation
-->
-->
...
@@ -53,12 +53,6 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
...
@@ -53,12 +53,6 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
<varlistentry>
<varlistentry>
<term>ACCESS SHARE MODE</term>
<term>ACCESS SHARE MODE</term>
<listitem>
<listitem>
<note>
<para>
This lock mode is acquired automatically over tables being queried.
</para>
</note>
<para>
<para>
This is the least restrictive lock mode. It conflicts only with
This is the least restrictive lock mode. It conflicts only with
ACCESS EXCLUSIVE mode. It is used to protect a table from being
ACCESS EXCLUSIVE mode. It is used to protect a table from being
...
@@ -66,108 +60,114 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
...
@@ -66,108 +60,114 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
<command>DROP TABLE</command> and <command>VACUUM FULL</command>
<command>DROP TABLE</command> and <command>VACUUM FULL</command>
commands.
commands.
</para>
</para>
<note>
<para>
The <command>SELECT</command> command acquires a
lock of this mode on referenced tables. In general, any query
that only reads a table and does not modify it will acquire
this lock mode.
</para>
</note>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>ROW SHARE MODE</term>
<term>ROW SHARE MODE</term>
<listitem>
<listitem>
<note>
<para>
<para>
Automatically acquired by <command>SELECT ... FOR UPDATE</command>
.
Conflicts with EXCLUSIVE and ACCESS EXCLUSIVE lock modes
.
</para>
</para>
</note>
<note>
<para>
<para>
Conflicts with EXCLUSIVE and ACCESS EXCLUSIVE lock modes.
The <command>SELECT FOR UPDATE</command> command acquires a
lock of this mode on the target table(s) (in addition to
<literal>ACCESS SHARE</literal> locks on any other tables
that are referenced but not selected <option>FOR UPDATE</option>).
</para>
</para>
</note>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>ROW EXCLUSIVE MODE</term>
<term>ROW EXCLUSIVE MODE</term>
<listitem>
<listitem>
<note>
<para>
<para>
Automatically acquired by <command>UPDATE</command>,
Conflicts with SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
<command>DELETE</command>, and <command>INSERT</command>
ACCESS EXCLUSIVE modes.
statements.
</para>
</para>
</note>
<note>
<para>
<para>
Conflicts with SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
The commands <command>UPDATE</command>,
ACCESS EXCLUSIVE modes.
<command>DELETE</command>, and <command>INSERT</command>
acquire this lock mode on the target table (in addition to
<literal>ACCESS SHARE</literal> locks on any other referenced
tables). In general, this lock mode will be acquired by any
query that modifies the data in a table.
</para>
</para>
</note>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>SHARE UPDATE EXCLUSIVE MODE</term>
<term>SHARE UPDATE EXCLUSIVE MODE</term>
<listitem>
<listitem>
<note>
<para>
Automatically acquired by <command>VACUUM</command> (without
<option>FULL</option>).
</para>
</note>
<para>
<para>
Conflicts with SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
Conflicts with SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
EXCLUSIVE and
EXCLUSIVE and
ACCESS EXCLUSIVE modes. This mode protects a table against
ACCESS EXCLUSIVE modes. This mode protects a table against
concurrent schema changes and VACUUMs.
concurrent schema changes and VACUUMs.
</para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SHARE MODE</term>
<listitem>
<note>
<note>
<para>
<para>
A
utomatically acquired by <command>CREATE INDEX</command>.
A
cquired by <command>VACUUM</command> (without
Share-locks the entire table
.
<option>FULL</option>)
.
</para>
</para>
</note>
</note>
</listitem>
</varlistentry>
<varlistentry>
<term>SHARE MODE</term>
<listitem>
<para>
<para>
Conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
Conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
SHARE ROW EXCLUSIVE, EXCLUSIVE and
SHARE ROW EXCLUSIVE, EXCLUSIVE and
ACCESS EXCLUSIVE modes. This mode protects a table against
ACCESS EXCLUSIVE modes. This mode protects a table against
concurrent data
updat
es.
concurrent data
chang
es.
</para>
</para>
<note>
<para>
Acquired by <command>CREATE INDEX</command>.
</para>
</note>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>SHARE ROW EXCLUSIVE MODE</term>
<term>SHARE ROW EXCLUSIVE MODE</term>
<listitem>
<listitem>
<note>
<para>
<para>
This is like EXCLUSIVE MODE, but allows ROW SHARE locks
Conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE,
by other
s.
SHARE ROW EXCLUSIVE, EXCLUSIVE and ACCESS EXCLUSIVE mode
s.
</para>
</para>
</note>
<note>
<para>
<para>
Conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE,
This lock mode is not automatically acquired by any
SHARE ROW EXCLUSIVE, EXCLUSIVE and ACCESS EXCLUSIVE modes
.
<productname>PostgreSQL</productname> command
.
</para>
</para>
</note>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>EXCLUSIVE MODE</term>
<term>EXCLUSIVE MODE</term>
<listitem>
<listitem>
<note>
<para>
This mode is yet more restrictive than SHARE ROW EXCLUSIVE.
It blocks all concurrent ROW SHARE/SELECT...FOR UPDATE queries.
</para>
</note>
<para>
<para>
Conflicts with ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
Conflicts with ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
SHARE, SHARE ROW EXCLUSIVE,
SHARE, SHARE ROW EXCLUSIVE,
...
@@ -176,33 +176,33 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
...
@@ -176,33 +176,33 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
from the table can proceed in parallel with a transaction holding
from the table can proceed in parallel with a transaction holding
this lock mode.
this lock mode.
</para>
</para>
<note>
<para>
This lock mode is not automatically acquired by any
<productname>PostgreSQL</productname> command.
</para>
</note>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>ACCESS EXCLUSIVE MODE</term>
<term>ACCESS EXCLUSIVE MODE</term>
<listitem>
<listitem>
<note>
<para>
<para>
Automatically acquired by <command>ALTER TABLE</command>,
Conflicts with all lock modes. This mode guarantees that the
<command>DROP TABLE</command>, <command>VACUUM FULL</command>
holder is the only transaction accessing the table in any way.
statements.
This is the most restrictive lock mode which
protects a locked table from any concurrent operations.
</para>
</para>
</note>
<note>
<note>
<para>
<para>
This lock mode is also acquired by an unqualified
Acquired by <command>ALTER TABLE</command>,
<command>LOCK TABLE</command> (i.e., the command without an explicit
<command>DROP TABLE</command>, and <command>VACUUM FULL</command>
lock mode option).
statements.
This is also the default lock mode for <command>LOCK TABLE</command>
statements that do not specify a mode explicitly.
</para>
</para>
</note>
</note>
<para>
Conflicts with all lock modes.
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
</variablelist>
</variablelist>
...
@@ -255,98 +255,64 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
...
@@ -255,98 +255,64 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
</title>
</title>
<para>
<para>
<command>LOCK TABLE</command> controls concurrent access to a table
<command>LOCK TABLE</command> obtains a table-level lock, waiting if
for the duration of a transaction.
necessary for any conflicting locks to be released. Once obtained,
<productname>PostgreSQL</productname> always uses the least restrictive
the lock is held for the remainder of the current transaction.
lock mode whenever possible. <command>LOCK TABLE</command>
(There is no <command>UNLOCK TABLE</command> command; locks are always
provides for cases when you might need more restrictive locking.
released at transaction end.)
</para>
<para>
<acronym>RDBMS</acronym> locking uses the following terminology:
<variablelist>
<varlistentry>
<term>EXCLUSIVE</term>
<listitem>
<para>
An exclusive lock prevents other locks of the same type from being
granted. (Note: ROW EXCLUSIVE mode does not follow this naming
convention perfectly, since it is shared at the level of the table;
it is exclusive only with respect to specific rows that are being
updated.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SHARE</term>
<listitem>
<para>
A shared lock allows others to also hold the same type of lock,
but prevents the corresponding EXCLUSIVE lock from being granted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ACCESS</term>
<listitem>
<para>
Locks table schema.
</para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ROW</term>
<listitem>
<para>
<para>
Locks individual rows.
When acquiring locks automatically for commands that reference tables,
</para>
<productname>PostgreSQL</productname> always uses the least restrictive
</listitem>
lock mode possible. <command>LOCK TABLE</command>
</varlistentry>
provides for cases when you might need more restrictive locking.
</variablelist>
</para>
</para>
<para>
<para>
For example, suppose an application runs a transaction at READ COMMITTED
For example, suppose an application runs a transaction at READ COMMITTED
isolation level and needs to ensure th
e existence of data in a table for
isolation level and needs to ensure th
at data in a table remains stable
the duration of the
for
the duration of the
transaction. To achieve this you could obtain SHARE lock mode over the
transaction. To achieve this you could obtain SHARE lock mode over the
table before querying. This will prevent concurrent data changes
table before querying. This will prevent concurrent data changes
and ensure
further read operations over the table see data in their
and ensure
subsequent reads of the table see a stable
actual current state, because SHARE lock mode conflicts with any
ROW
view of committed data, because SHARE lock mode conflicts with the
ROW
EXCLUSIVE lock acquired by writers, and your
EXCLUSIVE lock acquired by writers, and your
<command>LOCK TABLE <replaceable class="PARAMETER">name</replaceable> IN SHARE MODE</command>
<command>LOCK TABLE <replaceable class="PARAMETER">name</replaceable> IN SHARE MODE</command>
statement will wait until any concurrent write operations commit or
statement will wait until any concurrent holders of ROW EXCLUSIVE mode
rollback. Thus, once you obtain the lock, there are no uncommitted
commit or roll back. Thus, once you obtain the lock, there are no
writes outstanding.
uncommitted writes outstanding; furthermore none can begin until you
release the lock.
<note>
<note>
<para>
<para>
To read data in their actual current state when running a transaction
To achieve a similar effect when running a transaction
at the SERIALIZABLE isolation level, you have to execute the LOCK TABLE
at the SERIALIZABLE isolation level, you have to execute the
<command>LOCK TABLE</>
statement before executing any DML statement. A serializable
statement before executing any DML statement. A serializable
transaction's view of data will be frozen when its first DML statement
transaction's view of data will be frozen when its first DML statement
begins.
begins. A later <command>LOCK</> will still prevent concurrent writes
--- but it
won't ensure that what the transaction reads corresponds to the latest
committed values.
</para>
</para>
</note>
</note>
</para>
</para>
<para>
<para>
In addition to the requirements above, if a transaction is going to
If a transaction of this sort is going to
change data in a table, then SHARE ROW EXCLUSIVE lock mode should
change the data in the table, then it should use SHARE ROW EXCLUSIVE lock
be acquired to prevent deadlock conditions when two concurrent
mode instead of SHARE mode. This ensures that only one transaction of
transactions attempt to lock the table in SHARE mode and then
this type runs at a time. Without this, a deadlock is possible: two
try to change data in this table, both (implicitly) acquiring
transactions might both acquire SHARE mode, and then be unable to also
ROW EXCLUSIVE lock mode that conflicts with a concurrent SHARE lock.
acquire ROW EXCLUSIVE mode to actually perform their updates. (Note that
a transaction's own locks never conflict, so a transaction can acquire
ROW EXCLUSIVE mode when it holds SHARE mode --- but not if anyone else
holds SHARE mode.)
</para>
</para>
<para>
<para>
To continue with the deadlock (when two transactions wait for one another)
Two general rules may be followed to prevent deadlock conditions:
issue raised above, you should follow two general rules to prevent
deadlock conditions:
</para>
</para>
<itemizedlist>
<itemizedlist>
...
@@ -366,9 +332,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
...
@@ -366,9 +332,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
<listitem>
<listitem>
<para>
<para>
Transactions should acquire two conflicting lock modes only if
If multiple lock modes are involved for a single object,
one of them is self-conflicting (i.e., may be held by only one
transaction at a time). If multiple lock modes are involved,
then transactions should always acquire the most restrictive mode first.
then transactions should always acquire the most restrictive mode first.
</para>
</para>
...
@@ -380,16 +344,18 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
...
@@ -380,16 +344,18 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
</listitem>
</listitem>
</itemizedlist>
</itemizedlist>
<note>
<para>
<para>
<productname>PostgreSQL</productname> does detect deadlocks and will
<productname>PostgreSQL</productname> does detect deadlocks and will
rollback at least one waiting transaction to resolve the deadlock.
rollback at least one waiting transaction to resolve the deadlock.
If it is not practical to code an application to follow the above rules
strictly, an alternative solution is to be prepared to retry transactions
when they are aborted by deadlocks.
</para>
</para>
</note>
<para>
<para>
When locking multiple tables, the command LOCK a, b; is equivalent to LOCK
When locking multiple tables, the command <literal>LOCK a, b;</> is
a; LOCK b;. The tables are locked one-by-one in the order specified in the
equivalent to <literal>LOCK a; LOCK b;</>. The tables are locked one-by-one
in the order specified in the
<command>LOCK</command> command.
<command>LOCK</command> command.
</para>
</para>
...
@@ -415,6 +381,62 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
...
@@ -415,6 +381,62 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
lock will be dropped as soon as it is obtained.
lock will be dropped as soon as it is obtained.
</para>
</para>
<para>
<acronym>RDBMS</acronym> locking uses the following standard terminology:
<variablelist>
<varlistentry>
<term>EXCLUSIVE</term>
<listitem>
<para>
An exclusive lock prevents other locks of the same type from being
granted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SHARE</term>
<listitem>
<para>
A shared lock allows others to also hold the same type of lock,
but prevents the corresponding EXCLUSIVE lock from being granted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ACCESS</term>
<listitem>
<para>
Locks table schema.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ROW</term>
<listitem>
<para>
Locks individual rows.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
<productname>PostgreSQL</productname> does not follow this terminology
exactly. <command>LOCK TABLE</> only deals with table-level locks, and
so the mode names involving ROW are all misnomers. These mode names
should generally be read as indicating the intention of the user to
acquire row-level locks within the locked table. Also,
ROW EXCLUSIVE mode does not follow this naming convention accurately,
since it is a sharable table lock. Keep in mind that all the lock modes
have identical semantics so far as <command>LOCK TABLE</> is concerned,
differing only in the rules about which modes conflict with which.
</para>
</refsect2>
</refsect2>
</refsect1>
</refsect1>
...
@@ -424,7 +446,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
...
@@ -424,7 +446,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
</title>
</title>
<para>
<para>
Illustrate
a SHARE lock on a primary key table when going to perform
Obtain
a SHARE lock on a primary key table when going to perform
inserts into a foreign key table:
inserts into a foreign key table:
<programlisting>
<programlisting>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment