Access to transaction status
Started by Christian Plattnerover 22 years ago1 messages
Hi all,
I am currently implementing an experimental middleware based replicator for
a set
of fully replicated databases.
Do be able to handle all sorts of failures I needed two functions:
- A function to get the current XID
- A function which I can use later to tell if a given XID
commited/aborted/whatever
I did a small implementation of this (see attachment).
Could one of you hackers tell me if you think this is
- an ugly way of accessing the clog?
- totally wrong because I missed some point?
- or a good and correct idea :)
It would be very nice if someone had the time to have a short look into
this.
Greetings,
Christian
Attachments:
postgres_xid_func.capplication/octet-stream; name=postgres_xid_func.cDownload
/******************************************************************************
Functions to get information about transaction status.
Written by Christian A. Plattner, plattner{insert at}inf.ethz.ch
Last change: 19.06.2003
'uint32 ejdbc_get_xid()' returns the current xid
'text ejedbc_test_xid(uint32)' returns the status of the given xid
Possible outcomes:
"INVALID" : This xid has not been used up to now
"COMMITED" : This xid was committed
"ABORTED" : This xid was aborted
"INPROGRESS" : This xid was not commited nor aborted
(in case of read-only xid's, this will be also the final state).
*****************************************************************************/
#include "postgres.h"
#include "fmgr.h"
#include "access/xact.h"
#include "access/transam.h"
/* These prototypes just prevent possible warnings from gcc. */
Datum ejdbc_get_xid(PG_FUNCTION_ARGS);
Datum ejdbc_test_xid(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(ejdbc_get_xid);
Datum
ejdbc_get_xid(PG_FUNCTION_ARGS)
{
TransactionId my_xid = GetCurrentTransactionId();
PG_RETURN_UINT32(my_xid);
}
PG_FUNCTION_INFO_V1(ejdbc_test_xid);
Datum
ejdbc_test_xid(PG_FUNCTION_ARGS)
{
text *t = (text *) NULL;
char *answer = (char*) NULL;
TransactionId xid = PG_GETARG_UINT32(0);
TransactionId next_xid = ReadNewTransactionId();
/*
we could make the following faster by calling 'TransactionIdGetStatus' directly
but that would ignore the usage comment in the TransactionIdGetStatus function
*/
if (! TransactionIdPrecedes(xid, next_xid))
{
answer = "INVALID";
}
else if (TransactionIdDidCommit(xid))
{
answer = "COMMITTED";
}
else if (TransactionIdDidAbort(xid))
{
answer = "ABORTED";
}
else // lets ignore 0x03 and treat it as 0x00 (INPROGRESS)
{
answer = "INPROGRESS";
}
t = (text *) palloc(VARHDRSZ + strlen(answer));
VARATT_SIZEP(t) = VARHDRSZ + strlen(answer);
memcpy((void *) VARDATA(t), answer, strlen(answer));
PG_RETURN_TEXT_P(t);
}