Transaction IDs not the same in same transaction?

Started by Steve Vover 20 years ago14 messagesgeneral
Jump to latest
#1Steve V
dndlists@gmail.com

So I was finally able to get a compiled binary for the code in this
thread(thanks Magnus):
http://archives.postgresql.org/pgsql-general/2005-06/msg00709.php

So everything seemed to be fine with my GetCurrentTransactionID()
function call returning the txn ID for each query I would run(as far
as I could tell). Then I tried running a txn with multiple queries,
and instead of just having one txn ID, each query had it's own. Does
that make any sense? I was under the impression that a regular
transaction block would have one txn ID assigned to it for its
duration.

Here's the query I ran:

BEGIN;
UPDATE partners SET
partner_name = 'partner #5',
activity_status_id = 1
WHERE partner_id = 5;

UPDATE partners SET
partner_name = 'partner #7'
WHERE partner_id = 3;

COMMIT;

Should that have had the same txn ID for both of those? The
GetCurrentTransactionID call occurs in a trigger, would that have an
impact on the ID?

Thanks,
Steve

#2Michael Fuhr
mike@fuhr.org
In reply to: Steve V (#1)
Re: Transaction IDs not the same in same transaction?

On Sat, Oct 22, 2005 at 01:30:32PM -0700, Steve V wrote:

So I was finally able to get a compiled binary for the code in this
thread(thanks Magnus):
http://archives.postgresql.org/pgsql-general/2005-06/msg00709.php

So everything seemed to be fine with my GetCurrentTransactionID()
function call returning the txn ID for each query I would run(as far
as I could tell). Then I tried running a txn with multiple queries,
and instead of just having one txn ID, each query had it's own. Does
that make any sense? I was under the impression that a regular
transaction block would have one txn ID assigned to it for its
duration.

It makes sense if you're running PostgreSQL 8.0 or later and are
using subtransactions, whether explicitly or implicitly. The example
you posted didn't show the trigger definition or function -- does
the function do any error trapping? Maybe you need GetTopTransactionId()
instead of GetCurrentTransactionID().

Why do you need the transaction ID at all? Might the xmin system
column serve your purpose?

--
Michael Fuhr

#3Steve V
dndlists@gmail.com
In reply to: Michael Fuhr (#2)
Re: Transaction IDs not the same in same transaction?

On 10/22/05, Michael Fuhr <mike@fuhr.org> wrote:

It makes sense if you're running PostgreSQL 8.0 or later and are
using subtransactions, whether explicitly or implicitly. The example
you posted didn't show the trigger definition or function -- does
the function do any error trapping? Maybe you need GetTopTransactionId()
instead of GetCurrentTransactionID().

Why do you need the transaction ID at all? Might the xmin system
column serve your purpose?

Using 8.0.4 right now. No subtransactions that I know of. The trigger
call is an AFTER I/U/D. The function called is somewhat lengthy, but
it does not explicitly intiate any transactions, and does not perform
any error trapping.

Maybe GetTopTransactionId() is a better function call. I have no
experience with it though. I played around with
GetCurrentTransactionID(), and noticed the following behavior. If I
add an extra integer field to my table to hold txn IDs; I get the same
txn ID stored if both of my updates in the initial post call
GetCurrentTransactionID() as part of their updated field lists.
However, the txn IDs in from each of the triggers is different. So
with the previous scenario, I end up with a total of three distinct
txn IDs.

I'm using this for an auditing script, and want to use the txn ID to
indicate an atomic set of changes(the pg txn ID is mapped to my own
txn ID to avoid wraparound issues). I would rather not use xmin, as it
is not available directly in any of the triggers(as far as I know). So
I would have to construct select statements on the fly, and I would
rather not do that. I'm open to suggestions though.

Thanks,
Steve

#4Christian Kratzer
ck-lists@cksoft.de
In reply to: Steve V (#3)
Re: Transaction IDs not the same in same transaction?

Hi,

On Sat, 22 Oct 2005, Steve V wrote:

On 10/22/05, Michael Fuhr <mike@fuhr.org> wrote:

[snipp]

I'm using this for an auditing script, and want to use the txn ID to
indicate an atomic set of changes(the pg txn ID is mapped to my own
txn ID to avoid wraparound issues). I would rather not use xmin, as it
is not available directly in any of the triggers(as far as I know). So
I would have to construct select statements on the fly, and I would
rather not do that. I'm open to suggestions though.

we use a touple of (now(),session_backend_pid()) in our logging triggers
to identify stuff done in the same transaction.

now() will be frozen during the transaction and session_backend_pid()
disambuguates this for cases where two transaction could have the
same start time.

Greetings
Christian

--
Christian Kratzer ck@cksoft.de
CK Software GmbH http://www.cksoft.de/
Phone: +49 7452 889 135 Fax: +49 7452 889 136

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Steve V (#3)
Re: Transaction IDs not the same in same transaction?

Steve V <dndlists@gmail.com> writes:

Using 8.0.4 right now. No subtransactions that I know of. The trigger
call is an AFTER I/U/D. The function called is somewhat lengthy, but
it does not explicitly intiate any transactions, and does not perform
any error trapping.

I think that last assertion is probably in error, but without seeing the
full text of the trigger it's difficult to be sure what's going on here.

regards, tom lane

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Steve V (#1)
Re: Transaction IDs not the same in same transaction?

Steve V <dndlists@gmail.com> writes:

Well it doesn't explicitly do it, so the only thing I could think of
is that it has something to do with the pltcl spi_exec calls?

Ah, you had not even mentioned that the trigger was in pltcl.
spi_exec runs everything in subtransactions as of 8.0, so that
it can catch errors and propagate them back as Tcl errors.

regards, tom lane

In reply to: Christian Kratzer (#4)
Re: Transaction IDs not the same in same transaction?

Hi,

On Sun, 23 Oct 2005, Christian Kratzer wrote:

Hi,

On Sat, 22 Oct 2005, Steve V wrote:

On 10/22/05, Michael Fuhr <mike@fuhr.org> wrote:

[snipp]

I'm using this for an auditing script, and want to use the txn ID to
indicate an atomic set of changes(the pg txn ID is mapped to my own
txn ID to avoid wraparound issues). I would rather not use xmin, as it
is not available directly in any of the triggers(as far as I know). So
I would have to construct select statements on the fly, and I would
rather not do that. I'm open to suggestions though.

we use a touple of (now(),session_backend_pid()) in our logging triggers
to identify stuff done in the same transaction.

now() will be frozen during the transaction and session_backend_pid()
disambuguates this for cases where two transaction could have the
same start time.

I of course meant a tuple of now() and pg_backend_pid().

session_backend_pid is the name of a column in our session table.

Greetings
Christian

--
Christian Kratzer ck@cksoft.de
CK Software GmbH http://www.cksoft.de/
Phone: +49 7452 889 135 Fax: +49 7452 889 136

#8Steve V
dndlists@gmail.com
In reply to: Tom Lane (#6)
Re: Transaction IDs not the same in same transaction?

Ah, you had not even mentioned that the trigger was in pltcl.
spi_exec runs everything in subtransactions as of 8.0, so that
it can catch errors and propagate them back as Tcl errors.

Okay, so are there any possible options? Would GetTopTransactionId()
work, as Michael suggested further up?

Thanks,
Steve

#9Michael Fuhr
mike@fuhr.org
In reply to: Steve V (#8)
Re: Transaction IDs not the same in same transaction?

On Sun, Oct 23, 2005 at 02:00:47PM -0700, Steve V wrote:

Ah, you had not even mentioned that the trigger was in pltcl.
spi_exec runs everything in subtransactions as of 8.0, so that
it can catch errors and propagate them back as Tcl errors.

Okay, so are there any possible options? Would GetTopTransactionId()
work, as Michael suggested further up?

I just did some tests with a pltcl function that uses spi_exec in
an AFTER trigger and GetTopTransactionId() returned the same value
for each of several inserts and updates that were in the same
transaction. However, I can't say whether this will work for you
without seeing your code. It would be easier for us to help -- and
you'd get a solution sooner -- if you'd post a minimal but complete
example that shows what you're doing and that exhibits the behavior
you're seeing.

--
Michael Fuhr

#10Steve V
dndlists@gmail.com
In reply to: Michael Fuhr (#9)
Re: Transaction IDs not the same in same transaction?

I just did some tests with a pltcl function that uses spi_exec in
an AFTER trigger and GetTopTransactionId() returned the same value
for each of several inserts and updates that were in the same
transaction. However, I can't say whether this will work for you
without seeing your code. It would be easier for us to help -- and
you'd get a solution sooner -- if you'd post a minimal but complete
example that shows what you're doing and that exhibits the behavior
you're seeing.

Okay, so using GetTopTransactionId() will do the trick it sounds like.
To see all of what's happening, just place the pltcl function that I
posted earlier in this thread as an AFTER trigger, and run code
similar to that which I showed in my first post to start the thread.

Which library is GetTopTransactionId() available in? Do I need to
compile an library on my own that will expose it?

#11Neil Conway
neilc@samurai.com
In reply to: Steve V (#10)
Re: Transaction IDs not the same in same transaction?

On Sun, 2005-23-10 at 16:35 -0700, Steve V wrote:

Which library is GetTopTransactionId() available in?

It's defined in the backend executable, as is GetCurrentTransactionId().
A similar wrapper function to the one shown here:

http://archives.postgresql.org/pgsql-general/2005-06/msg00709.php

should work. But I agree with the other folks in this thread who have
questioned whether this is a good idea: backend APIs are known to change
significantly between releases, and making assumptions about how they
behave seems like asking for trouble to me.

-Neil

#12Michael Fuhr
mike@fuhr.org
In reply to: Steve V (#10)
Re: Transaction IDs not the same in same transaction?

On Sun, Oct 23, 2005 at 04:35:14PM -0700, Steve V wrote:

Okay, so using GetTopTransactionId() will do the trick it sounds like.
To see all of what's happening, just place the pltcl function that I
posted earlier in this thread as an AFTER trigger, and run code
similar to that which I showed in my first post to start the thread.

I haven't received that message yet, nor do I see it in the archives.
One of Tom Lane's replies appeared to quote from it -- did you send
it just to him? If you copied the list then the message might be
stuck somewhere.

Which library is GetTopTransactionId() available in? Do I need to
compile an library on my own that will expose it?

See "C-Language Functions" in the documentation, especially "Compiling
and Linking Dynamically-Loaded Functions" and "Extension Building
Infrastructure":

http://www.postgresql.org/docs/8.0/interactive/xfunc-c.html#DFUNC
http://www.postgresql.org/docs/8.0/interactive/xfunc-c.html#XFUNC-C-PGXS

What platform are you using? If Windows then see also the User Comments
at the bottom of the above pages.

Where did you get the GetCurrentTransactionId() code? Your first
message suggests that somebody named Magnus might have sent it to
you. If you don't have the means to build the code yourself then
perhaps that person could help again.

--
Michael Fuhr

#13Steve V
dndlists@gmail.com
In reply to: Michael Fuhr (#12)
Re: Transaction IDs not the same in same transaction?

I haven't received that message yet, nor do I see it in the archives.
One of Tom Lane's replies appeared to quote from it -- did you send
it just to him? If you copied the list then the message might be
stuck somewhere.

Yeah, I accidentally only sent it to Tom. Sorry about that.

What platform are you using? If Windows then see also the User Comments
at the bottom of the above pages.

Where did you get the GetCurrentTransactionId() code? Your first
message suggests that somebody named Magnus might have sent it to
you. If you don't have the means to build the code yourself then
perhaps that person could help again.

Yeah, I'm on a Win32 platform for the time being. The
GetCurrentTransactionID() code was posted in response to one of my
threads a few months back. Magnus Hagander from the hackers-win32 list
was the one that was kind enough to compile the code for me. I'll see
if he doesn't mind whipping up another library for me.

Thanks,
Steve

#14Steve V
dndlists@gmail.com
In reply to: Neil Conway (#11)
Re: Transaction IDs not the same in same transaction?

It's defined in the backend executable, as is GetCurrentTransactionId().
A similar wrapper function to the one shown here:

http://archives.postgresql.org/pgsql-general/2005-06/msg00709.php

should work. But I agree with the other folks in this thread who have
questioned whether this is a good idea: backend APIs are known to change
significantly between releases, and making assumptions about how they
behave seems like asking for trouble to me.

I agree with all of you as well that using backend APIs is not the
most continually reliable way of doing this. Unfortunately the
requirement stands that I need to audit all actions that occur in a
single transaction, as one group.

Christian's method seems like it should work properly. Does anyone see
any problems with doing it in the fashion mentioned by him?