8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.73 2008/01/01 19:45:48 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.74 2008/03/11 20:20:35 tgl Exp $
12
12
*
13
13
* NOTES
14
14
* This file contains the high level access-method interface to the
25
25
#include "utils/tqual.h"
26
26
27
27
28
- static XidStatus TransactionLogFetch (TransactionId transactionId );
29
- static void TransactionLogUpdate (TransactionId transactionId ,
30
- XidStatus status , XLogRecPtr lsn );
31
-
32
28
/*
33
- * Single-item cache for results of TransactionLogFetch.
29
+ * Single-item cache for results of TransactionLogFetch. It's worth having
30
+ * such a cache because we frequently find ourselves repeatedly checking the
31
+ * same XID, for example when scanning a table just after a bulk insert,
32
+ * update, or delete.
34
33
*/
35
34
static TransactionId cachedFetchXid = InvalidTransactionId ;
36
35
static XidStatus cachedFetchXidStatus ;
@@ -39,9 +38,14 @@ static XLogRecPtr cachedCommitLSN;
39
38
/* Handy constant for an invalid xlog recptr */
40
39
static const XLogRecPtr InvalidXLogRecPtr = {0 , 0 };
41
40
41
+ /* Local functions */
42
+ static XidStatus TransactionLogFetch (TransactionId transactionId );
43
+ static void TransactionLogUpdate (TransactionId transactionId ,
44
+ XidStatus status , XLogRecPtr lsn );
45
+
42
46
43
47
/* ----------------------------------------------------------------
44
- * postgres log access method interface
48
+ * Postgres log access method interface
45
49
*
46
50
* TransactionLogFetch
47
51
* TransactionLogUpdate
@@ -82,8 +86,8 @@ TransactionLogFetch(TransactionId transactionId)
82
86
xidstatus = TransactionIdGetStatus (transactionId , & xidlsn );
83
87
84
88
/*
85
- * DO NOT cache status for unfinished or sub-committed transactions! We
86
- * only cache status that is guaranteed not to change.
89
+ * Cache it, but DO NOT cache status for unfinished or sub-committed
90
+ * transactions! We only cache status that is guaranteed not to change.
87
91
*/
88
92
if (xidstatus != TRANSACTION_STATUS_IN_PROGRESS &&
89
93
xidstatus != TRANSACTION_STATUS_SUB_COMMITTED )
@@ -96,12 +100,11 @@ TransactionLogFetch(TransactionId transactionId)
96
100
return xidstatus ;
97
101
}
98
102
99
- /* --------------------------------
103
+ /*
100
104
* TransactionLogUpdate
101
105
*
102
106
* Store the new status of a transaction. The commit record LSN must be
103
107
* passed when recording an async commit; else it should be InvalidXLogRecPtr.
104
- * --------------------------------
105
108
*/
106
109
static inline void
107
110
TransactionLogUpdate (TransactionId transactionId ,
@@ -131,32 +134,27 @@ TransactionLogMultiUpdate(int nxids, TransactionId *xids,
131
134
TransactionIdSetStatus (xids [i ], status , lsn );
132
135
}
133
136
137
+
134
138
/* ----------------------------------------------------------------
135
139
* Interface functions
136
140
*
137
- * TransactionId DidCommit
138
- * TransactionId DidAbort
139
- * TransactionId IsInProgress
141
+ * TransactionIdDidCommit
142
+ * TransactionIdDidAbort
140
143
* ========
141
144
* these functions test the transaction status of
142
145
* a specified transaction id.
143
146
*
144
- * TransactionId Commit
145
- * TransactionId Abort
147
+ * TransactionIdCommit
148
+ * TransactionIdAbort
146
149
* ========
147
150
* these functions set the transaction status
148
151
* of the specified xid.
149
152
*
153
+ * See also TransactionIdIsInProgress, which once was in this module
154
+ * but now lives in procarray.c.
150
155
* ----------------------------------------------------------------
151
156
*/
152
157
153
- /* --------------------------------
154
- * TransactionId DidCommit
155
- * TransactionId DidAbort
156
- * TransactionId IsInProgress
157
- * --------------------------------
158
- */
159
-
160
158
/*
161
159
* TransactionIdDidCommit
162
160
* True iff transaction associated with the identifier did commit.
@@ -262,11 +260,33 @@ TransactionIdDidAbort(TransactionId transactionId)
262
260
return false;
263
261
}
264
262
265
- /* --------------------------------
266
- * TransactionId Commit
267
- * TransactionId Abort
268
- * --------------------------------
263
+ /*
264
+ * TransactionIdIsKnownCompleted
265
+ * True iff transaction associated with the identifier is currently
266
+ * known to have either committed or aborted.
267
+ *
268
+ * This does NOT look into pg_clog but merely probes our local cache
269
+ * (and so it's not named TransactionIdDidComplete, which would be the
270
+ * appropriate name for a function that worked that way). The intended
271
+ * use is just to short-circuit TransactionIdIsInProgress calls when doing
272
+ * repeated tqual.c checks for the same XID. If this isn't extremely fast
273
+ * then it will be counterproductive.
274
+ *
275
+ * Note:
276
+ * Assumes transaction identifier is valid.
269
277
*/
278
+ bool
279
+ TransactionIdIsKnownCompleted (TransactionId transactionId )
280
+ {
281
+ if (TransactionIdEquals (transactionId , cachedFetchXid ))
282
+ {
283
+ /* If it's in the cache at all, it must be completed. */
284
+ return true;
285
+ }
286
+
287
+ return false;
288
+ }
289
+
270
290
271
291
/*
272
292
* TransactionIdCommit
@@ -292,7 +312,6 @@ TransactionIdAsyncCommit(TransactionId transactionId, XLogRecPtr lsn)
292
312
TransactionLogUpdate (transactionId , TRANSACTION_STATUS_COMMITTED , lsn );
293
313
}
294
314
295
-
296
315
/*
297
316
* TransactionIdAbort
298
317
* Aborts the transaction associated with the identifier.
@@ -352,7 +371,6 @@ TransactionIdAsyncCommitTree(int nxids, TransactionId *xids, XLogRecPtr lsn)
352
371
lsn );
353
372
}
354
373
355
-
356
374
/*
357
375
* TransactionIdAbortTree
358
376
* Marks all the given transaction ids as aborted.
@@ -368,6 +386,7 @@ TransactionIdAbortTree(int nxids, TransactionId *xids)
368
386
InvalidXLogRecPtr );
369
387
}
370
388
389
+
371
390
/*
372
391
* TransactionIdPrecedes --- is id1 logically < id2?
373
392
*/
0 commit comments