Commit c0b4b42c authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

MVCC updation.

parent ccdad51a
...@@ -25,7 +25,7 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E ...@@ -25,7 +25,7 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
<refsect2 id="R2-SQL-LOCK-1"> <refsect2 id="R2-SQL-LOCK-1">
<refsect2info> <refsect2info>
<date>1998-09-01</date> <date>1999-06-09</date>
</refsect2info> </refsect2info>
<title> <title>
Inputs Inputs
...@@ -46,73 +46,140 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E ...@@ -46,73 +46,140 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
<varlistentry> <varlistentry>
<term> <term>
SHARE MODE ACCESS SHARE MODE
</term> </term>
<listitem> <listitem>
<note>
<para> <para>
This lock mode is acquired automatically over tables being queried.
<productname>Postgres</productname> releases automatically acquired
ACCESS SHARE locks after statement is done.
</para>
</note>
<para>
This is the less restrictive lock mode which conflicts with
ACCESS EXCLUSIVE mode only. It's intended to protect table being
queried from concurrent <command>ALTER TABLE</command>,
<command>DROP TABLE</command> and <command>VACUUM</command>
statements over the same table.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
EXCLUSIVE MODE ROW SHARE MODE
</term> </term>
<listitem> <listitem>
<note>
<para> <para>
Automatically acquired by <command>SELECT FOR UPDATE</command> statement.
</para>
</note>
<para>
Conflicts with EXCLUSIVE and ACCESS EXCLUSIVE lock modes.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
ROW SHARE MODE ROW EXCLUSIVE MODE
</term> </term>
<listitem> <listitem>
<note>
<para> <para>
Automatically acquired by <command>UPDATE</command>,
<command>DELETE</command>, <command>INSERT</command> statements.
</para>
</note>
<para>
Conflicts with SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
ACCESS EXCLUSIVE modes. Generally means that a transaction
updated/inserted some tuples in a table.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
ROW EXCLUSIVE MODE SHARE MODE
</term> </term>
<listitem> <listitem>
<note>
<para> <para>
Automatically acquired by <command>CREATE INDEX</command> statement.
</para>
</note>
<para>
Conflicts with ROW EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
ACCESS EXCLUSIVE modes. This mode protects a table against
concurrent updates.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
ACCESS SHARE MODE SHARE ROW EXCLUSIVE MODE
</term> </term>
<listitem> <listitem>
<para>
<para>
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.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
ACCESS EXCLUSIVE MODE EXCLUSIVE MODE
</term> </term>
<listitem> <listitem>
<para>
<para>
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.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
SHARE ROW EXCLUSIVE MODE ACCESS EXCLUSIVE MODE
</term> </term>
<listitem> <listitem>
<note>
<para> <para>
</para> Automatically acquired by <command>ALTER TABLE</command>,
<command>DROP TABLE</command>, <command>VACUUM</command> statements.
</para>
</note>
<para>
This is the most restrictive lock mode which conflicts with all other
lock modes and protects locked table from any concurrent operations.
</para>
<note>
<para>
This lock mode is also acquired by first form of
<command>LOCK TABLE</command> (i.e. without explicit
lock mode option).
</para>
</note>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</para> </para>
</refsect2> </refsect2>
...@@ -151,36 +218,73 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E ...@@ -151,36 +218,73 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
Description Description
</title> </title>
<para> <para>
By default, <command>LOCK</command> locks in exclusive mode a table inside <productname>Postgres</productname> always uses less restrictive
a transaction. Various options allow shared access, or row-level locking lock modes ever possible. <command>LOCK TABLE</command> statement
control. The classic use for this is provided for cases when you might need in more restrictive locking.
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
<command>UPDATE</command>, <command>INSERT</command>,
or <command>DELETE</command> 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.
</para> </para>
<para>
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).
</para>
<para> <para>
Another example of deadlock is where one user locks one If, in addition to requirements above, transaction is going to
table, and another user locks a second table. While both change data in a table then SHARE ROW EXCLUSIVE lock mode should
keep their existing locks, the first user tries to lock be acquired to prevent deadlock conditions when two concurrent
the second user's table, and the second user tries to lock transactions would lock table in SHARE mode and than would
the first user's table. Both users deadlock waiting for try to change data in this table, both (implicitly) acquiring
the tables to become available. The only solution to this ROW EXCLUSIVE lock mode that conflicts with concurrent SHARE lock.
is for both users to lock tables in the same order, so
user's lock acquisitions and requests to not form a deadlock.
</para> </para>
<para>
Following deadlock issue (when two transaction wait one another)
touched above, you should follow two general rules to prevent
deadlock conditions:
</para>
<listitem>
<para>
Transactions have to acquire locks on the same objects in the same order.
</para>
<para>
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.
</para>
</listitem>
<listitem>
<para>
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.
</para>
<para>
Example for this rule is described above when told about using
SHARE ROW EXCLUSIVE mode instead of SHARE one.
</para>
</listitem>
<note> <note>
<para> <para>
<productname>Postgres</productname> does detect deadlocks and will <productname>Postgres</productname> does detect deadlocks and will
rollback transactions to resolve the deadlock. Usually, at least one rollback one of waiting transactions to resolve the deadlock.
of the deadlocked transactions will complete successfully.
</para> </para>
</note> </note>
...@@ -195,16 +299,13 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E ...@@ -195,16 +299,13 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
<command>LOCK</command> is a <productname>Postgres</productname> <command>LOCK</command> is a <productname>Postgres</productname>
language extension. language extension.
</para> </para>
<para>
Except for ACCESS SHARE/EXCLUSIVE lock modes, all other
<productname>Postgres</productname> lock modes and
<command>LOCK TABLE</command> syntax are compatible with
<productname>Oracle</productname> ones.
<para> <para>
<command>LOCK</command> works only inside transactions. <command>LOCK</command> works only inside transactions.
<note>
<title>Bug</title>
<para>
If the locked table is dropped then it will be automatically
unlocked even if a transaction is still in progress.
</para>
</note>
</para> </para>
</refsect2> </refsect2>
</refsect1> </refsect1>
...@@ -213,18 +314,40 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E ...@@ -213,18 +314,40 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
<title> <title>
Usage Usage
</title> </title>
<para> <para>
<programlisting>
--
-- SHARE lock primary key table when going to perform
-- insert into foreign key table.
--
BEGIN WORK;
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;
</programlisting>
</para> </para>
<para>
<programlisting> <programlisting>
--Explicit locking to prevent deadlock: --
-- SHARE ROW EXCLUSIVE lock primary key table when going to perform
-- delete operation.
-- --
BEGIN WORK; BEGIN WORK;
LOCK films; LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
SELECT * FROM films; DELETE FROM films_user_comments WHERE id IN
UPDATE films SET len = INTERVAL '100 minute' (SELECT id FROM films WHERE rating < 5);
WHERE len = INTERVAL '117 minute'; DELETE FROM films WHERE rating < 5;
COMMIT WORK; COMMIT WORK;
</programlisting> </programlisting>
</para>
</refsect1> </refsect1>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<synopsis> <synopsis>
SET <replaceable class="PARAMETER">variable</replaceable> { TO | = } { '<replaceable class="PARAMETER">value</replaceable>' | DEFAULT } SET <replaceable class="PARAMETER">variable</replaceable> { TO | = } { '<replaceable class="PARAMETER">value</replaceable>' | DEFAULT }
SET TIME ZONE { '<replaceable class="PARAMETER">timezone</replaceable>' | LOCAL | DEFAULT }; SET TIME ZONE { '<replaceable class="PARAMETER">timezone</replaceable>' | LOCAL | DEFAULT };
SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT } SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED }
</synopsis> </synopsis>
<refsect2 id="R2-SQL-SET-1"> <refsect2 id="R2-SQL-SET-1">
...@@ -350,36 +350,33 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT } ...@@ -350,36 +350,33 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT }
</term> </term>
<listitem> <listitem>
<para> <para>
The current transaction reads only The current transaction queries read only rows committed
committed rows. READ COMMITTED is the default. before a query began. READ COMMITTED is the default.
</para> </para>
</listitem>
</varlistentry> <note>
<varlistentry>
<term>
SERIALIZABLE
</term>
<listitem>
<para> <para>
The current transaction will place a <acronym>SQL92</acronym> standard requires
lock on every row read, so later reads in that transaction SERIALIZABLE to be the default isolation level.
see the rows unmodified by other transactions.
</para> </para>
</note>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
DEFAULT SERIALIZABLE
</term> </term>
<listitem> <listitem>
<para> <para>
Sets the isolation level for the current transaction to The current transaction queries read only rows committed
<option>READ COMMITTED</option>. before first DML statement
(<command>SELECT/INSERT/DELETE/UPDATE/FETCH/COPY_TO</command>)
was executed in this transaction.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</para> </para>
</listitem> </listitem>
...@@ -789,7 +786,7 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT } ...@@ -789,7 +786,7 @@ SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZED | DEFAULT }
<para> <para>
There is no There is no
<command>SET <replaceable class="parameter">variable</replaceable></command> <command>SET <replaceable class="parameter">variable</replaceable></command>
in <acronym>SQL92</acronym>. in <acronym>SQL92</acronym> (except for SET TRANSACTION ISOLATION LEVEL).
The <acronym>SQL92</acronym> syntax for <command>SET TIME ZONE</command> The <acronym>SQL92</acronym> syntax for <command>SET TIME ZONE</command>
is slightly different, is slightly different,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment