I want to update one row from possibly several backends. In case
of SERIALIZABLE transactions, the update command may fail. To
hide it from calling transaction, I use a subtransaction and try
to catch and hide the error.
With help of plpgsql source, I wrote following code that _seems_
to work. But I have no idea if it's the correct way to do it:
/* store old state */MemoryContext oldcontext = CurrentMemoryContext;ResourceOwner oldowner = CurrentResourceOwner;
BeginInternalSubTransaction(NULL);res = SPI_connect();if (res < 0) elog(ERROR, "cannot connect to SPI");
PG_TRY();{ res = SPI_execute("update one row", false, 0); SPI_finish();
ReleaseCurrentSubTransaction();}PG_CATCH();{ SPI_finish(); RollbackAndReleaseCurrentSubTransaction();
FlushErrorState(); res = -1; /* remember failure */}PG_END_TRY();
/* restore old state */MemoryContextSwitchTo(oldcontext);CurrentResourceOwner = oldowner;
I am suspicious about the ..SubTransaction and SPI_* nesting
and resetting the error state. Can anyone look if it's correct?
Goal of the exercise is to have 8-byte transaction ID's and snapshots
externally available. (Port of xxid module from Slony). Above code
does the update of the 'epoch' table that has only one row.
--
marko