Skip to content

Commit 6d6d14b

Browse files
committed
Redefine IsTransactionState() to only return true for TRANS_INPROGRESS state,
which is the only state in which it's safe to initiate database queries. It turns out that all but two of the callers thought that's what it meant; and the other two were using it as a proxy for "will GetTopTransactionId() return a nonzero XID"? Since it was in fact an unreliable guide to that, make those two just invoke GetTopTransactionId() always, then deal with a zero result if they get one.
1 parent 24ee8af commit 6d6d14b

File tree

3 files changed

+23
-39
lines changed

3 files changed

+23
-39
lines changed

src/backend/access/transam/xact.c

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.244 2007/05/30 21:01:39 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.245 2007/06/07 21:45:58 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -64,12 +64,12 @@ int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
6464
*/
6565
typedef enum TransState
6666
{
67-
TRANS_DEFAULT,
68-
TRANS_START,
69-
TRANS_INPROGRESS,
70-
TRANS_COMMIT,
71-
TRANS_ABORT,
72-
TRANS_PREPARE
67+
TRANS_DEFAULT, /* idle */
68+
TRANS_START, /* transaction starting */
69+
TRANS_INPROGRESS, /* inside a valid transaction */
70+
TRANS_COMMIT, /* commit in progress */
71+
TRANS_ABORT, /* abort in progress */
72+
TRANS_PREPARE /* prepare in progress */
7373
} TransState;
7474

7575
/*
@@ -255,34 +255,22 @@ static const char *TransStateAsString(TransState state);
255255
/*
256256
* IsTransactionState
257257
*
258-
* This returns true if we are currently running a query
259-
* within an executing transaction.
258+
* This returns true if we are inside a valid transaction; that is,
259+
* it is safe to initiate database access, take heavyweight locks, etc.
260260
*/
261261
bool
262262
IsTransactionState(void)
263263
{
264264
TransactionState s = CurrentTransactionState;
265265

266-
switch (s->state)
267-
{
268-
case TRANS_DEFAULT:
269-
return false;
270-
case TRANS_START:
271-
return true;
272-
case TRANS_INPROGRESS:
273-
return true;
274-
case TRANS_COMMIT:
275-
return true;
276-
case TRANS_ABORT:
277-
return true;
278-
case TRANS_PREPARE:
279-
return true;
280-
}
281-
282266
/*
283-
* Shouldn't get here, but lint is not happy without this...
267+
* TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However,
268+
* we also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
269+
* TRANS_PREPARE since it might be too soon or too late within those
270+
* transition states to do anything interesting. Hence, the only "valid"
271+
* state is TRANS_INPROGRESS.
284272
*/
285-
return false;
273+
return (s->state == TRANS_INPROGRESS);
286274
}
287275

288276
/*
@@ -308,7 +296,9 @@ IsAbortedTransactionBlockState(void)
308296
* GetTopTransactionId
309297
*
310298
* Get the ID of the main transaction, even if we are currently inside
311-
* a subtransaction.
299+
* a subtransaction. If we are not in a transaction at all, or if we
300+
* are in transaction startup and haven't yet assigned an XID,
301+
* InvalidTransactionId is returned.
312302
*/
313303
TransactionId
314304
GetTopTransactionId(void)

src/backend/storage/ipc/procarray.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
*
2525
* IDENTIFICATION
26-
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.25 2007/06/01 19:38:07 tgl Exp $
26+
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.26 2007/06/07 21:45:59 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -422,9 +422,8 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
422422
* are no xacts running at all, that will be the subtrans truncation
423423
* point!)
424424
*/
425-
if (IsTransactionState())
426-
result = GetTopTransactionId();
427-
else
425+
result = GetTopTransactionId();
426+
if (!TransactionIdIsValid(result))
428427
result = ReadNewTransactionId();
429428

430429
LWLockAcquire(ProcArrayLock, LW_SHARED);

src/backend/utils/error/elog.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
*
4343
*
4444
* IDENTIFICATION
45-
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.185 2007/05/04 02:01:02 tgl Exp $
45+
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.186 2007/06/07 21:45:59 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -1593,12 +1593,7 @@ log_line_prefix(StringInfo buf)
15931593
break;
15941594
case 'x':
15951595
if (MyProcPort)
1596-
{
1597-
if (IsTransactionState())
1598-
appendStringInfo(buf, "%u", GetTopTransactionId());
1599-
else
1600-
appendStringInfo(buf, "%u", InvalidTransactionId);
1601-
}
1596+
appendStringInfo(buf, "%u", GetTopTransactionId());
16021597
break;
16031598
case '%':
16041599
appendStringInfoChar(buf, '%');

0 commit comments

Comments
 (0)