mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Use the standard lock manager to establish priority order when there
is contention for a tuple-level lock. This solves the problem of a would-be exclusive locker being starved out by an indefinite succession of share-lockers. Per recent discussion with Alvaro.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.72 2005/04/29 22:28:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.73 2005/04/30 19:03:33 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -339,6 +339,46 @@ UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
|
||||
LockRelease(LockTableId, &tag, GetTopTransactionId(), lockmode);
|
||||
}
|
||||
|
||||
/*
|
||||
* LockTuple
|
||||
*
|
||||
* Obtain a tuple-level lock. This is used in a less-than-intuitive fashion
|
||||
* because we can't afford to keep a separate lock in shared memory for every
|
||||
* tuple. See heap_lock_tuple before using this!
|
||||
*/
|
||||
void
|
||||
LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_TUPLE(tag,
|
||||
relation->rd_lockInfo.lockRelId.dbId,
|
||||
relation->rd_lockInfo.lockRelId.relId,
|
||||
ItemPointerGetBlockNumber(tid),
|
||||
ItemPointerGetOffsetNumber(tid));
|
||||
|
||||
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
|
||||
lockmode, false))
|
||||
elog(ERROR, "LockAcquire failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* UnlockTuple
|
||||
*/
|
||||
void
|
||||
UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_TUPLE(tag,
|
||||
relation->rd_lockInfo.lockRelId.dbId,
|
||||
relation->rd_lockInfo.lockRelId.relId,
|
||||
ItemPointerGetBlockNumber(tid),
|
||||
ItemPointerGetOffsetNumber(tid));
|
||||
|
||||
LockRelease(LockTableId, &tag, GetTopTransactionId(), lockmode);
|
||||
}
|
||||
|
||||
/*
|
||||
* XactLockTableInsert
|
||||
*
|
||||
@@ -417,3 +457,87 @@ XactLockTableWait(TransactionId xid)
|
||||
if (!TransactionIdDidCommit(xid) && !TransactionIdDidAbort(xid))
|
||||
TransactionIdAbort(xid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LockDatabaseObject
|
||||
*
|
||||
* Obtain a lock on a general object of the current database. Don't use
|
||||
* this for shared objects (such as tablespaces). It's usually unwise to
|
||||
* apply it to entire relations, also, since a lock taken this way will
|
||||
* NOT conflict with LockRelation.
|
||||
*/
|
||||
void
|
||||
LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
|
||||
LOCKMODE lockmode)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_OBJECT(tag,
|
||||
MyDatabaseId,
|
||||
classid,
|
||||
objid,
|
||||
objsubid);
|
||||
|
||||
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
|
||||
lockmode, false))
|
||||
elog(ERROR, "LockAcquire failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* UnlockDatabaseObject
|
||||
*/
|
||||
void
|
||||
UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
|
||||
LOCKMODE lockmode)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_OBJECT(tag,
|
||||
MyDatabaseId,
|
||||
classid,
|
||||
objid,
|
||||
objsubid);
|
||||
|
||||
LockRelease(LockTableId, &tag, GetTopTransactionId(), lockmode);
|
||||
}
|
||||
|
||||
/*
|
||||
* LockSharedObject
|
||||
*
|
||||
* Obtain a lock on a shared-across-databases object.
|
||||
*/
|
||||
void
|
||||
LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
|
||||
LOCKMODE lockmode)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_OBJECT(tag,
|
||||
InvalidOid,
|
||||
classid,
|
||||
objid,
|
||||
objsubid);
|
||||
|
||||
if (!LockAcquire(LockTableId, &tag, GetTopTransactionId(),
|
||||
lockmode, false))
|
||||
elog(ERROR, "LockAcquire failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* UnlockSharedObject
|
||||
*/
|
||||
void
|
||||
UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
|
||||
LOCKMODE lockmode)
|
||||
{
|
||||
LOCKTAG tag;
|
||||
|
||||
SET_LOCKTAG_OBJECT(tag,
|
||||
InvalidOid,
|
||||
classid,
|
||||
objid,
|
||||
objsubid);
|
||||
|
||||
LockRelease(LockTableId, &tag, GetTopTransactionId(), lockmode);
|
||||
}
|
||||
|
Reference in New Issue
Block a user