Hi hackers,
 
I found a problem when doing the test shown below:
         
Time
         
Session A
         
Session B
     
        
T1
         
postgres=# create table test(a int);
   
CREATE TABLE
   
postgres=# insert into test values (1);
   
INSERT 0 1
         
 
     
        
T2
         
postgres=# 
begin;                                     
 
   
BEGIN                                                 
   
   
postgres=*# lock table test in access exclusive mode ; 
   
LOCK 
TABLE                                            
 
         
 
     
        
T3
         
 
         
postgres=# begin;
   
BEGIN
   
postgres=*# lock table test in exclusive mode ;
     
        
T4
         
Case 1:
   
postgres=*# lock table test in share row exclusive mode   nowait; 
   
ERROR:  could not   obtain lock on relation 
"test"               
 
   
--------------------------------------------
   
Case 2:
   
postgres=*# lock table test in share row exclusive mode;
   
LOCK TABLE
         
 
     
  
At T4 moment in session A, (case 1) when executing SQL ??lock table test in 
share row exclusive mode nowait;??, an error occurs with message ??could not 
obtain lock on relation test";However, (case 2) when executing the SQL above 
without nowait, lock can be obtained successfully. 
 
Digging into the source code, I find that in case 2 the lock was obtained in 
the function ProcSleep instead of LockAcquireExtended. Due to nowait logic 
processed before WaitOnLock->ProcSleep, acquiring lock failed in case 1. Can 
any changes be made so that the act of such lock granted occurs before 
WaitOnLock?
 
 
 
Providing a more universal case:
 
Transaction A already holds an n-mode lock on table test. If then transaction A 
requests an m-mode lock on table Test, m and n have the following constraints:
 
(lockMethodTable->conflictTab[n] & lockMethodTable->conflictTab[m]) 
== lockMethodTable->conflictTab[m]
 
Obviously, in this case, m<=n.
 
Should the m-mode lock be granted before WaitOnLock?
 
&nbsp;
 
In the case of m=n (i.e. we already hold the lock), the m-mode lock is 
immediately granted in the LocalLock path, without the need of lock conflict 
check.
 
Based on the facts above, can we obtain a weaker lock (m<n) on the same object 
within the same transaction without doing lock conflict check?
 
Since m=n works, m<n should certainly work too.
 
&nbsp;
 
I am attaching a patch here with which the problem in case 1 fixed.




With&nbsp;Regards,
Jingxian Li.


&nbsp;

Attachment: v1-0001-LockAcquireExtended-improvement.patch
Description: Binary data

Reply via email to