mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Add NOWAIT option to SELECT FOR UPDATE/SHARE.
Original patch by Hans-Juergen Schoenig, revisions by Karel Zak and Tom Lane.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.195 2005/06/20 18:37:01 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.196 2005/08/01 20:31:05 tgl Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@@ -1945,7 +1945,7 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
|
||||
*/
|
||||
HTSU_Result
|
||||
heap_lock_tuple(Relation relation, HeapTuple tuple, Buffer *buffer,
|
||||
CommandId cid, LockTupleMode mode)
|
||||
CommandId cid, LockTupleMode mode, bool nowait)
|
||||
{
|
||||
HTSU_Result result;
|
||||
ItemPointer tid = &(tuple->t_self);
|
||||
@@ -1998,7 +1998,16 @@ l3:
|
||||
*/
|
||||
if (!have_tuple_lock)
|
||||
{
|
||||
LockTuple(relation, tid, tuple_lock_type);
|
||||
if (nowait)
|
||||
{
|
||||
if (!ConditionalLockTuple(relation, tid, tuple_lock_type))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
|
||||
errmsg("could not obtain lock on row in relation \"%s\"",
|
||||
RelationGetRelationName(relation))));
|
||||
}
|
||||
else
|
||||
LockTuple(relation, tid, tuple_lock_type);
|
||||
have_tuple_lock = true;
|
||||
}
|
||||
|
||||
@@ -2020,7 +2029,17 @@ l3:
|
||||
else if (infomask & HEAP_XMAX_IS_MULTI)
|
||||
{
|
||||
/* wait for multixact to end */
|
||||
MultiXactIdWait((MultiXactId) xwait);
|
||||
if (nowait)
|
||||
{
|
||||
if (!ConditionalMultiXactIdWait((MultiXactId) xwait))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
|
||||
errmsg("could not obtain lock on row in relation \"%s\"",
|
||||
RelationGetRelationName(relation))));
|
||||
}
|
||||
else
|
||||
MultiXactIdWait((MultiXactId) xwait);
|
||||
|
||||
LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
|
||||
/*
|
||||
@@ -2045,7 +2064,17 @@ l3:
|
||||
else
|
||||
{
|
||||
/* wait for regular transaction to end */
|
||||
XactLockTableWait(xwait);
|
||||
if (nowait)
|
||||
{
|
||||
if (!ConditionalXactLockTableWait(xwait))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
|
||||
errmsg("could not obtain lock on row in relation \"%s\"",
|
||||
RelationGetRelationName(relation))));
|
||||
}
|
||||
else
|
||||
XactLockTableWait(xwait);
|
||||
|
||||
LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
|
||||
/*
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.5 2005/06/08 15:50:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.6 2005/08/01 20:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -558,6 +558,43 @@ MultiXactIdWait(MultiXactId multi)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ConditionalMultiXactIdWait
|
||||
* As above, but only lock if we can get the lock without blocking.
|
||||
*/
|
||||
bool
|
||||
ConditionalMultiXactIdWait(MultiXactId multi)
|
||||
{
|
||||
bool result = true;
|
||||
TransactionId *members;
|
||||
int nmembers;
|
||||
|
||||
nmembers = GetMultiXactIdMembers(multi, &members);
|
||||
|
||||
if (nmembers >= 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nmembers; i++)
|
||||
{
|
||||
TransactionId member = members[i];
|
||||
|
||||
debug_elog4(DEBUG2, "ConditionalMultiXactIdWait: trying %d (%u)",
|
||||
i, member);
|
||||
if (!TransactionIdIsCurrentTransactionId(member))
|
||||
{
|
||||
result = ConditionalXactLockTableWait(member);
|
||||
if (!result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pfree(members);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateMultiXactId
|
||||
* Make a new MultiXactId
|
||||
@@ -590,7 +627,7 @@ CreateMultiXactId(int nxids, TransactionId *xids)
|
||||
*/
|
||||
multi = mXactCacheGetBySet(nxids, xids);
|
||||
if (MultiXactIdIsValid(multi))
|
||||
{
|
||||
{
|
||||
debug_elog2(DEBUG2, "Create: in cache!");
|
||||
return multi;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user