aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/async.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-06-17 22:32:51 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-06-17 22:32:51 +0000
commitd0a89683a3a4dd8e76ef0a99101355999e519df5 (patch)
treeb19aaf7f03cbcc851b00ca6e472cc7d3e5a20ca1 /src/backend/commands/async.c
parent5495575903e35ceb40d32055ab55e9377460208f (diff)
downloadpostgresql-d0a89683a3a4dd8e76ef0a99101355999e519df5.tar.gz
postgresql-d0a89683a3a4dd8e76ef0a99101355999e519df5.zip
Two-phase commit. Original patch by Heikki Linnakangas, with additional
hacking by Alvaro Herrera and Tom Lane.
Diffstat (limited to 'src/backend/commands/async.c')
-rw-r--r--src/backend/commands/async.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 9914c724b71..142b02dfaf8 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.122 2005/05/06 17:24:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.123 2005/06/17 22:32:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -78,6 +78,7 @@
#include <netinet/in.h>
#include "access/heapam.h"
+#include "access/twophase_rmgr.h"
#include "catalog/pg_listener.h"
#include "commands/async.h"
#include "libpq/libpq.h"
@@ -407,6 +408,36 @@ Async_UnlistenOnExit(int code, Datum arg)
CommitTransactionCommand();
}
+
+/*
+ *--------------------------------------------------------------
+ * AtPrepare_Notify
+ *
+ * This is called at the prepare phase of a two-phase
+ * transaction. Save the state for possible commit later.
+ *--------------------------------------------------------------
+ */
+void
+AtPrepare_Notify(void)
+{
+ ListCell *p;
+
+ foreach(p, pendingNotifies)
+ {
+ const char *relname = (const char *) lfirst(p);
+
+ RegisterTwoPhaseRecord(TWOPHASE_RM_NOTIFY_ID, 0,
+ relname, strlen(relname) + 1);
+ }
+
+ /*
+ * We can clear the state immediately, rather than needing a separate
+ * PostPrepare call, because if the transaction fails we'd just
+ * discard the state anyway.
+ */
+ ClearPendingNotifies();
+}
+
/*
*--------------------------------------------------------------
* AtCommit_Notify
@@ -1016,8 +1047,9 @@ AsyncExistsPendingNotify(const char *relname)
foreach(p, pendingNotifies)
{
- /* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */
- if (strncmp((const char *) lfirst(p), relname, NAMEDATALEN) == 0)
+ const char *prelname = (const char *) lfirst(p);
+
+ if (strcmp(prelname, relname) == 0)
return true;
}
@@ -1037,3 +1069,22 @@ ClearPendingNotifies(void)
*/
pendingNotifies = NIL;
}
+
+/*
+ * 2PC processing routine for COMMIT PREPARED case.
+ *
+ * (We don't have to do anything for ROLLBACK PREPARED.)
+ */
+void
+notify_twophase_postcommit(TransactionId xid, uint16 info,
+ void *recdata, uint32 len)
+{
+ /*
+ * Set up to issue the NOTIFY at the end of my own
+ * current transaction. (XXX this has some issues if my own
+ * transaction later rolls back, or if there is any significant
+ * delay before I commit. OK for now because we disallow
+ * COMMIT PREPARED inside a transaction block.)
+ */
+ Async_Notify((char *) recdata);
+}