diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-08-01 20:31:16 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-08-01 20:31:16 +0000 |
| commit | 2a4fad1a0e43d6375ffa8eddb2d8dfa1ed36593f (patch) | |
| tree | bb2bc2208507b0ab2403850e8dd01003a4ed73e9 /src/backend/access | |
| parent | ca7abcd89dbeecb82cde50fccf4f6c483244fdf7 (diff) | |
| download | postgresql-2a4fad1a0e43d6375ffa8eddb2d8dfa1ed36593f.tar.gz | |
Add NOWAIT option to SELECT FOR UPDATE/SHARE.
Original patch by Hans-Juergen Schoenig, revisions by Karel Zak
and Tom Lane.
Diffstat (limited to 'src/backend/access')
| -rw-r--r-- | src/backend/access/heap/heapam.c | 39 | ||||
| -rw-r--r-- | src/backend/access/transam/multixact.c | 41 |
2 files changed, 73 insertions, 7 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 843b2909ef..c5851765f2 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -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); /* diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 41773625af..8f107d42c6 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -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 $ * *------------------------------------------------------------------------- */ @@ -559,6 +559,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; } |
