@@ -25,7 +25,7 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
2525
2626 <refsect2 id="R2-SQL-LOCK-1">
2727 <refsect2info>
28- <date>1998-09-01 </date>
28+ <date>1999-06-09 </date>
2929 </refsect2info>
3030 <title>
3131 Inputs
@@ -46,73 +46,140 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
4646
4747 <varlistentry>
4848 <term>
49- SHARE MODE
49+ ACCESS SHARE MODE
5050 </term>
5151 <listitem>
52+ <note>
5253 <para>
54+ This lock mode is acquired automatically over tables being queried.
55+ <productname>Postgres</productname> releases automatically acquired
56+ ACCESS SHARE locks after statement is done.
57+ </para>
58+ </note>
59+
60+ <para>
61+ This is the less restrictive lock mode which conflicts with
62+ ACCESS EXCLUSIVE mode only. It's intended to protect table being
63+ queried from concurrent <command>ALTER TABLE</command>,
64+ <command>DROP TABLE</command> and <command>VACUUM</command>
65+ statements over the same table.
5366 </para>
5467 </listitem>
5568 </varlistentry>
5669
5770 <varlistentry>
5871 <term>
59- EXCLUSIVE MODE
72+ ROW SHARE MODE
6073 </term>
6174 <listitem>
75+ <note>
6276 <para>
77+ Automatically acquired by <command>SELECT FOR UPDATE</command> statement.
78+ </para>
79+ </note>
80+
81+ <para>
82+ Conflicts with EXCLUSIVE and ACCESS EXCLUSIVE lock modes.
6383 </para>
6484 </listitem>
6585 </varlistentry>
6686
6787 <varlistentry>
6888 <term>
69- ROWSHARE MODE
89+ ROWEXCLUSIVE MODE
7090 </term>
7191 <listitem>
92+ <note>
7293 <para>
94+ Automatically acquired by <command>UPDATE</command>,
95+ <command>DELETE</command>, <command>INSERT</command> statements.
96+ </para>
97+ </note>
98+
99+ <para>
100+ Conflicts with SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
101+ ACCESS EXCLUSIVE modes. Generally means that a transaction
102+ updated/inserted some tuples in a table.
73103 </para>
74104 </listitem>
75105 </varlistentry>
76106
77107 <varlistentry>
78108 <term>
79- ROW EXCLUSIVE MODE
109+ SHARE MODE
80110 </term>
81111 <listitem>
112+ <note>
82113 <para>
114+ Automatically acquired by <command>CREATE INDEX</command> statement.
115+ </para>
116+ </note>
117+
118+ <para>
119+ Conflicts with ROW EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE and
120+ ACCESS EXCLUSIVE modes. This mode protects a table against
121+ concurrent updates.
83122 </para>
84123 </listitem>
85124 </varlistentry>
86125
87126 <varlistentry>
88127 <term>
89- ACCESS SHARE MODE
128+ SHARE ROW EXCLUSIVE MODE
90129 </term>
91130 <listitem>
92- <para>
131+
132+ <para>
133+ Conflicts with ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
134+ EXCLUSIVE and ACCESS EXCLUSIVE modes. This mode is more
135+ restrictive than SHARE mode because of only one transaction
136+ at time can hold this lock.
93137 </para>
94138 </listitem>
95139 </varlistentry>
96140
97141 <varlistentry>
98142 <term>
99- ACCESS EXCLUSIVE MODE
143+ EXCLUSIVE MODE
100144 </term>
101145 <listitem>
102- <para>
146+
147+ <para>
148+ Conflicts with ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
149+ EXCLUSIVE and ACCESS EXCLUSIVE modes. This mode is yet more
150+ restrictive than SHARE ROW EXCLUSIVE one - it blocks concurrent
151+ SELECT FOR UPDATE queries.
103152 </para>
104153 </listitem>
105154 </varlistentry>
106155
107156 <varlistentry>
108157 <term>
109- SHARE ROW EXCLUSIVE MODE
158+ ACCESS EXCLUSIVE MODE
110159 </term>
111160 <listitem>
161+ <note>
112162 <para>
113- </para>
163+ Automatically acquired by <command>ALTER TABLE</command>,
164+ <command>DROP TABLE</command>, <command>VACUUM</command> statements.
165+ </para>
166+ </note>
167+
168+ <para>
169+ This is the most restrictive lock mode which conflicts with all other
170+ lock modes and protects locked table from any concurrent operations.
171+ </para>
172+
173+ <note>
174+ <para>
175+ This lock mode is also acquired by first form of
176+ <command>LOCK TABLE</command> (i.e. without explicit
177+ lock mode option).
178+ </para>
179+ </note>
114180 </listitem>
115181 </varlistentry>
182+
116183 </variablelist>
117184 </para>
118185 </refsect2>
@@ -151,36 +218,73 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
151218 Description
152219 </title>
153220 <para>
154- By default, <command>LOCK</command> locks in exclusive mode a table inside
155- a transaction. Various options allow shared access, or row-level locking
156- control. The classic use for this is
157- the case where you want to select some data, then
158- update it inside a transaction.
159- If you don't explicit lock a table using LOCK statement, it will be
160- implicit locked only at the first
161- <command>UPDATE</command>, <command>INSERT</command>,
162- or <command>DELETE</command> operation.
163- If you don't exclusive lock the table before the select, some
164- other user may also read the selected data, and try and do
165- their own update, causing a deadlock while you both wait
166- for the other to release the select-induced shared lock so
167- you can get an exclusive lock to do the update.
221+ <productname>Postgres</productname> always uses less restrictive
222+ lock modes ever possible. <command>LOCK TABLE</command> statement
223+ provided for cases when you might need in more restrictive locking.
168224 </para>
225+
226+ <para>
227+ For example, application run transaction at READ COMMITTED isolation
228+ level and need to ensure existance data in a table for duration of
229+ transaction. To achieve this you could use SHARE lock mode over
230+ table before querying. This will protect data from concurrent changes
231+ and provide your further read operations over table with data in their
232+ real current state, because of SHARE lock mode conflicts with ROW EXCLUSIVE
233+ one, acquired by writers, and your LOCK TABLE table IN SHARE MODE statement
234+ will wait untill concurrent write operations (if any) commit/rollback.
235+ (Note that to read data in their real current state running transaction
236+ at SERIALIZABLE isolation level you have to execute LOCK TABLE
237+ statement before execution any DML statement, when transaction defines
238+ what concurrent changes will be visible to herself).
239+ </para>
240+
169241 <para>
170- Another example of deadlock is where one user locks one
171- table, and another user locks a second table. While both
172- keep their existing locks, the first user tries to lock
173- the second user's table, and the second user tries to lock
174- the first user's table. Both users deadlock waiting for
175- the tables to become available. The only solution to this
176- is for both users to lock tables in the same order, so
177- user's lock acquisitions and requests to not form a deadlock.
242+ If, in addition to requirements above, transaction is going to
243+ change data in a table then SHARE ROW EXCLUSIVE lock mode should
244+ be acquired to prevent deadlock conditions when two concurrent
245+ transactions would lock table in SHARE mode and than would
246+ try to change data in this table, both (implicitly) acquiring
247+ ROW EXCLUSIVE lock mode that conflicts with concurrent SHARE lock.
178248 </para>
249+
250+ <para>
251+ Following deadlock issue (when two transaction wait one another)
252+ touched above, you should follow two general rules to prevent
253+ deadlock conditions:
254+ </para>
255+
256+ <listitem>
257+ <para>
258+ Transactions have to acquire locks on the same objects in the same order.
259+ </para>
260+
261+ <para>
262+ For example, if one application updates row R1 and than updates
263+ row R2 (in the same transaction) then second application shouldn't
264+ update row R2 if it's going update row R1 later (in single transaction).
265+ Instead, it should update R1 and R2 rows in the same order as first
266+ application.
267+ </para>
268+ </listitem>
269+
270+ <listitem>
271+ <para>
272+ Transactions should acquire two conflicting lock modes only if
273+ one of them is self-conflicting (i.e. may be held by one
274+ transaction at time only) and should acquire most restrictive
275+ mode first.
276+ </para>
277+
278+ <para>
279+ Example for this rule is described above when told about using
280+ SHARE ROW EXCLUSIVE mode instead of SHARE one.
281+ </para>
282+ </listitem>
283+
179284 <note>
180285 <para>
181286 <productname>Postgres</productname> does detect deadlocks and will
182- rollback transactions to resolve the deadlock. Usually, at least one
183- of the deadlocked transactions will complete successfully.
287+ rollback one of waiting transactions to resolve the deadlock.
184288 </para>
185289 </note>
186290
@@ -195,16 +299,13 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
195299 <command>LOCK</command> is a <productname>Postgres</productname>
196300 language extension.
197301 </para>
302+ <para>
303+ Except for ACCESS SHARE/EXCLUSIVE lock modes, all other
304+ <productname>Postgres</productname> lock modes and
305+ <command>LOCK TABLE</command> syntax are compatible with
306+ <productname>Oracle</productname> ones.
198307 <para>
199308 <command>LOCK</command> works only inside transactions.
200-
201- <note>
202- <title>Bug</title>
203- <para>
204- If the locked table is dropped then it will be automatically
205- unlocked even if a transaction is still in progress.
206- </para>
207- </note>
208309 </para>
209310 </refsect2>
210311 </refsect1>
@@ -213,18 +314,40 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">table</replaceable> IN SHARE ROW E
213314 <title>
214315 Usage
215316 </title>
317+
216318 <para>
319+ <programlisting>
320+ --
321+ -- SHARE lock primary key table when going to perform
322+ -- insert into foreign key table.
323+ --
324+ BEGIN WORK;
325+ LOCK TABLE films IN SHARE MODE;
326+ SELECT id FROM films
327+ WHERE name = 'Star Wars: Episode I - The Phantom Menace';
328+ --
329+ -- Do ROLLBACK if record was not returned
330+ --
331+ INSERT INTO films_user_comments VALUES
332+ (_id_, 'GREAT! I was waiting it so long!');
333+ COMMIT WORK;
334+ </programlisting>
217335 </para>
336+
337+ <para>
218338 <programlisting>
219- --Explicit locking to prevent deadlock:
339+ --
340+ -- SHARE ROW EXCLUSIVE lock primary key table when going to perform
341+ -- delete operation.
220342 --
221343 BEGIN WORK;
222- LOCK films;
223- SELECT * FROMfilms;
224- UPDATE films SET len = INTERVAL '100 minute'
225- WHERElen = INTERVAL '117 minute' ;
344+ LOCKTABLE films IN SHARE ROW EXCLUSIVE MODE ;
345+ DELETE FROMfilms_user_comments WHERE id IN
346+ (SELECT id FROM films WHERE rating < 5);
347+ DELETE FROM films WHERErating < 5 ;
226348 COMMIT WORK;
227349 </programlisting>
350+ </para>
228351
229352 </refsect1>
230353