mirror of
https://github.com/postgres/postgres.git
synced 2025-10-12 07:05:03 +03:00
Add support to lock manager for conditionally locking a lock (ie,
return without waiting if we can't get the lock immediately). Not used yet, but will be needed for concurrent VACUUM.
This commit is contained in:
@@ -5,9 +5,8 @@ This software is distributed under the GNU General Public License
|
||||
either version 2, or (at your option) any later version.
|
||||
|
||||
|
||||
This loadable module, together with my user-lock.patch applied to the
|
||||
backend, provides support for user-level long-term cooperative locks.
|
||||
For example one can write:
|
||||
This loadable module provides support for user-level long-term cooperative
|
||||
locks. For example one can write:
|
||||
|
||||
select some_fields, user_write_lock_oid(oid) from table where id='key';
|
||||
|
||||
@@ -26,14 +25,14 @@ After you have finished your work on that item you can do:
|
||||
You can also ignore the failure and go ahead but this could produce conflicts
|
||||
or inconsistent data in your application. User locks require a cooperative
|
||||
behavior between users. User locks don't interfere with the normal locks
|
||||
used by postgres for transaction processing.
|
||||
used by Postgres for transaction processing.
|
||||
|
||||
This could also be done by setting a flag in the record itself but in
|
||||
this case you have the overhead of the updates to the records and there
|
||||
could be some locks not released if the backend or the application crashes
|
||||
before resetting the lock flag.
|
||||
It could also be done with a begin/end block but in this case the entire
|
||||
table would be locked by postgres and it is not acceptable to do this for
|
||||
table would be locked by Postgres and it is not acceptable to do this for
|
||||
a long period because other transactions would block completely.
|
||||
|
||||
The generic user locks use two values, group and id, to identify a lock,
|
||||
@@ -44,12 +43,12 @@ use a group equal to 0.
|
||||
|
||||
The meaning of group and id is defined by the application. The user
|
||||
lock code just takes two numbers and tells you if the corresponding
|
||||
entity has been succesfully locked. What this mean is up to you.
|
||||
entity has been successfully locked. What this means is up to you.
|
||||
|
||||
My succestion is that you use the group to identify an area of your
|
||||
My suggestion is that you use the group to identify an area of your
|
||||
application and the id to identify an object in this area.
|
||||
Or you can just lock the oid of the tuples which are by definition unique.
|
||||
|
||||
Note also that a process can acquire more than one lock on the same entity
|
||||
and it must release the lock the corresponding number of times. This can
|
||||
be done calling the unlock funtion until it returns 0.
|
||||
be done by calling the unlock function until it returns 0.
|
||||
|
@@ -1,27 +1,23 @@
|
||||
/*
|
||||
* user_locks.c --
|
||||
*
|
||||
* This loadable module, together with my user-lock.patch applied to the
|
||||
* backend, provides support for user-level long-term cooperative locks.
|
||||
* This loadable module provides support for user-level long-term
|
||||
* cooperative locks.
|
||||
*
|
||||
* Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
|
||||
*
|
||||
* This software is distributed under the GNU General Public License
|
||||
* either version 2, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "miscadmin.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "storage/proc.h"
|
||||
#include "utils/elog.h"
|
||||
|
||||
#include "user_locks.h"
|
||||
|
||||
|
||||
int
|
||||
user_lock(uint32 id1, uint32 id2, LOCKMODE lockmode)
|
||||
{
|
||||
@@ -33,7 +29,8 @@ user_lock(uint32 id1, uint32 id2, LOCKMODE lockmode)
|
||||
tag.objId.blkno = (BlockNumber) id2;
|
||||
tag.offnum = (OffsetNumber) (id1 & 0xffff);
|
||||
|
||||
return LockAcquire(USER_LOCKMETHOD, &tag, InvalidTransactionId, lockmode);
|
||||
return LockAcquire(USER_LOCKMETHOD, &tag, InvalidTransactionId,
|
||||
lockmode, true);
|
||||
}
|
||||
|
||||
int
|
||||
|
Reference in New Issue
Block a user