Access to transaction status

Started by Christian Plattnerover 22 years ago1 messages
#1Christian Plattner
plattner@inf.ethz.ch
1 attachment(s)

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);
}