Thread: 2PC transaction id

2PC transaction id

From
Dave Cramer
Date:
Do the transaction id's used in 2PC need to be unique across all  
sessions?

Do we provide a mechanism for this ?

If not shouldn't we provide a way to create a unique transaction id ?


Dave Cramer
davec@postgresintl.com
www.postgresintl.com
ICQ #14675561
jabber davecramer@jabber.org
ph (519 939 0336 )



Re: 2PC transaction id

From
Alvaro Herrera
Date:
On Thu, Jun 30, 2005 at 06:39:43PM -0400, Dave Cramer wrote:
> Do the transaction id's used in 2PC need to be unique across all  
> sessions?

Yes.

> Do we provide a mechanism for this ?

Huh, the constraint is enforced by the server, but the ID is generated
by the client.

> If not shouldn't we provide a way to create a unique transaction id ?

Maybe a new function would suffice.

-- 
Alvaro Herrera (<alvherre[a]surnet.cl>)
"Use it up, wear it out, make it do, or do without"


Re: 2PC transaction id

From
Dave Cramer
Date:
In reality all it takes is a sequence, however if it were system  
generated it would be simpler

Dave
On 30-Jun-05, at 6:46 PM, Alvaro Herrera wrote:

> On Thu, Jun 30, 2005 at 06:39:43PM -0400, Dave Cramer wrote:
>
>> Do the transaction id's used in 2PC need to be unique across all
>> sessions?
>>
>
> Yes.
>
>
>> Do we provide a mechanism for this ?
>>
>
> Huh, the constraint is enforced by the server, but the ID is generated
> by the client.
>
>
>> If not shouldn't we provide a way to create a unique transaction id ?
>>
>
> Maybe a new function would suffice.
>
> -- 
> Alvaro Herrera (<alvherre[a]surnet.cl>)
> "Use it up, wear it out, make it do, or do without"
>
>



Re: 2PC transaction id

From
Oliver Jowett
Date:
Dave Cramer wrote:
> Do the transaction id's used in 2PC need to be unique across all  sessions?

They are global IDs, yes.

> Do we provide a mechanism for this ?
> 
> If not shouldn't we provide a way to create a unique transaction id ?

Well, in XA the XIDs are assigned by the TM, the individual resources
(e.g. a postgresql backend) just get *given* an XID to use.

-O


Re: 2PC transaction id

From
Dave Cramer
Date:
I'm thinking of the situation where one transaction occurs on more  
than one backend, and there is
more than one transaction manager.

Dave
On 30-Jun-05, at 7:37 PM, Oliver Jowett wrote:

> Dave Cramer wrote:
>
>> Do the transaction id's used in 2PC need to be unique across all   
>> sessions?
>>
>
> They are global IDs, yes.
>
>
>> Do we provide a mechanism for this ?
>>
>> If not shouldn't we provide a way to create a unique transaction id ?
>>
>
> Well, in XA the XIDs are assigned by the TM, the individual resources
> (e.g. a postgresql backend) just get *given* an XID to use.
>
> -O
>
> ---------------------------(end of  
> broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to  
> majordomo@postgresql.org
>
>



Re: 2PC transaction id

From
Oliver Jowett
Date:
Dave Cramer wrote:
> I'm thinking of the situation where one transaction occurs on more  than
> one backend, and there is
> more than one transaction manager.

XA XIDs are *global* IDs, i.e. they are unique even with more than one
TM involved. It's the responsibility of the TM to generate a
globally-unique XID.

If you have two different databases involved in the same global
transaction, then yes, the two backends could be told to use the same
global XID. That's normal. (they don't *have* to be given the same XID
as they could be participating in two independent branches of the same
global transaction, and in that case the global XIDs will have different
branch qualifiers)

It's even possible for one resource to do two different independent
(local) transactions that are part of the same global transaction -- in
that case, the local transactions will be given different XIDs though.

But all of this allocation / management of XIDs is done by the TM, the
individual resources don't need to do anything beyond associating
particular transactions with client-supplied XIDs, which we already do
AFAIK.

-O


Re: 2PC transaction id

From
Oliver Jowett
Date:
Oliver Jowett wrote:

> If you have two different databases involved in the same global
> transaction, then yes, the two backends could be told to use the same
> global XID. That's normal. (they don't *have* to be given the same XID
> as they could be participating in two independent branches of the same
> global transaction, and in that case the global XIDs will have different
> branch qualifiers)

Thinking about this some more -- it may be necessary for the same XID to
be associated with more than one backend transaction at once, possibly
even in the same database. This could happen if there are two clients
involved in the same global transaction with no branch qualifier change,
or if one client manages to get two separate resources that point at the
same database.

[... experiments ...]

Ok, so the second case is actually even more general, since
pg_prepared_xacts is scoped cluster-wide not database-wide. So any
global transaction that involves two databases on the same cluster could
be affected.

It seems that you can't PREPARE TRANSACTION more than once (per cluster)
with the same GID. That's a bit painful..

Can we make the GID-to-internal-xid mapping for prepared transactions
1:N rather than the current 1:1? COMMIT PREPARED and ROLLBACK PREPARED
would need either syntax or behaviour changes: either we need to
identify a particular transaction (perhaps via the xid from
pg_prepared_xacts.transaction), or they need to operate on *all*
transactions with the given GID.

I have no idea on how nasty it is to implement this though :)

Heikki, any thoughts?

-O

PS: noticed in passing: psql's help doesn't seem to know about the 2PC
command syntax yet.


Re: 2PC transaction id

From
Dave Cramer
Date:
On 30-Jun-05, at 8:00 PM, Oliver Jowett wrote:

> Dave Cramer wrote:
>
>> I'm thinking of the situation where one transaction occurs on  
>> more  than
>> one backend, and there is
>> more than one transaction manager.
>>
>
> XA XIDs are *global* IDs, i.e. they are unique even with more than one
> TM involved. It's the responsibility of the TM to generate a
> globally-unique XID.
>
> If you have two different databases involved in the same global
> transaction, then yes, the two backends could be told to use the same
> global XID. That's normal. (they don't *have* to be given the same XID
> as they could be participating in two independent branches of the same
> global transaction, and in that case the global XIDs will have  
> different
> branch qualifiers)
I understand this
>
> It's even possible for one resource to do two different independent
> (local) transactions that are part of the same global transaction  
> -- in
> that case, the local transactions will be given different XIDs though.
>
> But all of this allocation / management of XIDs is done by the TM, the
> individual resources don't need to do anything beyond associating
> particular transactions with client-supplied XIDs, which we already do
> AFAIK.
I was actually thinking more of the people without the advantage of  
an application server
Also for the case where some lowlevel replicator wanted to use 2PC.  
Probably a moot point
as anyone capable of writing one is also capable of getting a unique XID
>
> -O
>
> ---------------------------(end of  
> broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
>                http://archives.postgresql.org
>
>



Re: 2PC transaction id

From
Tom Lane
Date:
Dave Cramer <pg@fastcrypt.com> writes:
> Do the transaction id's used in 2PC need to be unique across all  
> sessions?
> Do we provide a mechanism for this ?
> If not shouldn't we provide a way to create a unique transaction id ?

I see no value in that at all.  The point of 2PC is to synchronize with
other databases running other transactions; an ID assigned by one
database that can only be guaranteed unique with respect to that
database is really pretty useless.  In practice the IDs will be assigned
by the transaction manager module according to its own needs.
        regards, tom lane


Re: 2PC transaction id

From
Tom Lane
Date:
Oliver Jowett <oliver@opencloud.com> writes:
> Can we make the GID-to-internal-xid mapping for prepared transactions
> 1:N rather than the current 1:1?

No.
        regards, tom lane


Re: 2PC transaction id

From
Oliver Jowett
Date:
Tom Lane wrote:
> Oliver Jowett <oliver@opencloud.com> writes:
> 
>>Can we make the GID-to-internal-xid mapping for prepared transactions
>>1:N rather than the current 1:1?
> 
> 
> No.

Ok, so how do we get XA working when a single global transaction
involves two databases on the same cluster?

The scenario is:

- there are two independent resource managers participating in a single
global transaction
- each resource manager has a connection to the database it is managing,
and a SQL-level transaction running against that database
- the global TM tells both resource managers to prepare their part of
the global transaction, passing the same XID to both
- the resource manager translates the xa_prepare() call to a PREPARE
TRANSACTION query, using the passed XID as the GID.

Currently, one of the PREPARE TRANSACTIONs is going to fail if the two
databases happen to be running under the same postmaster.

For this particular case we could embed the database name in the GID,
but unfortunately that doesn't work in the more general case where you
could have two RMs (perhaps in different processes) talking to the same
database.

Perhaps the second and subsequent RM to prepare could detect the
duplicate GID and add a sequence number or something similar to the end
-- and reverse this process on commit/rollback/recovery -- but I don't
see how you'd do this atomically with the PREPARE TRANSACTION.

-O


Re: 2PC transaction id

From
Tom Lane
Date:
Oliver Jowett <oliver@opencloud.com> writes:
> Ok, so how do we get XA working when a single global transaction
> involves two databases on the same cluster?

It's the TM's responsibility to deal with that.  I would expect it to
hand out transaction IDs that consist of a common prefix and a
per-database suffix, if it does not know which resources it's dealing
with might share a common GID namespace.

There's a reason that the XA spec has such a ridiculously large
requirement for the length of a GID name, and it is that this is the
TM's problem not ours.
        regards, tom lane


Re: 2PC transaction id

From
Oliver Jowett
Date:
Tom Lane wrote:
> Oliver Jowett <oliver@opencloud.com> writes:
> 
>>Ok, so how do we get XA working when a single global transaction
>>involves two databases on the same cluster?
> 
> 
> It's the TM's responsibility to deal with that.  I would expect it to
> hand out transaction IDs that consist of a common prefix and a
> per-database suffix, if it does not know which resources it's dealing
> with might share a common GID namespace.

Hm, that's not how I read the spec :(  Throughout the API is the
implication that you can have more than one RM associated with a
transaction branch.

For example, 3.3.1 says:

> 3.3.1 Registration of Resource Managers
> Normally, a TM involves all associated RMs in a transaction branch. (The TM’s set of
> RM switches, described in Section 4.3 on page 21 tells the TM which RMs are
> associated with it.) The TM calls all these RMs with xa_start(), xa_end(), and
> xa_prepare (), although an RM that is not active in a branch need not participate further
> (see Section 2.3.2 on page 8). A technique to reduce overhead for infrequently-used
> RMs is discussed below.

I don't know if we can reasonably expect TMs not to hand out an
identical XID to different RMs in the same global transaction.

(anyone with experience with how existing TMs behave want to chime in?)

-O


Re: 2PC transaction id

From
Oliver Jowett
Date:
Oliver Jowett wrote:
> Tom Lane wrote:
> 
>>It's the TM's responsibility to deal with that.  I would expect it to
>>hand out transaction IDs that consist of a common prefix and a
>>per-database suffix, if it does not know which resources it's dealing
>>with might share a common GID namespace.

> I don't know if we can reasonably expect TMs not to hand out an
> identical XID to different RMs in the same global transaction.

Hm, I suppose we *can* assume that a TM won't hand out the same XID to
the same RM twice (except for the special case of TMJOIN), so we could
append a per-database suffix in the RM itself (e.g. JDBC driver) to
avoid conflicts within a database cluster.

-O


Re: 2PC transaction id

From
Heikki Linnakangas
Date:
On Fri, 1 Jul 2005, Oliver Jowett wrote:

> Ok, so how do we get XA working when a single global transaction
> involves two databases on the same cluster?
>
> The scenario is:
>
> - there are two independent resource managers participating in a single
> global transaction
> - each resource manager has a connection to the database it is managing,
> and a SQL-level transaction running against that database
> - the global TM tells both resource managers to prepare their part of
> the global transaction, passing the same XID to both

If the TM does that, it's broken.

The XID consists of three parts:

format id: a constant. Not interesting.

gtrid: Global Transaction Identifier. This identifies the global 
transaction in the TM. All XIDs that have the same gtrid should be 
completed atomically by the TM

branch id: Branch Identifier. Every RM involved in the global transaction 
is given a *different* branch id.

In the above case, the TM would give the two resource managers XIDs that 
have the same gtrid but different branch ids.

From the RM point of view, those fields have no significance and the XID 
as whole is used to identify the transaction.

So the RM should never see the same XID twice, except when the TM 
specifically uses the TMJOIN or the TMSUSPEND/TMRESUME flags. If the TM 
uses those flags, it'll only issue one prepare.

- Heikki


Re: 2PC transaction id

From
Heikki Linnakangas
Date:
On Fri, 1 Jul 2005, Oliver Jowett wrote:

> Heikki Linnakangas wrote:
>
>> branch id: Branch Identifier. Every RM involved in the global
>> transaction is given a *different* branch id.
>
> Hm, I am confused then -- the XA spec definitely talks about enlisting
> multiple RMs in a single transaction branch.
>
> Can you explain?

I oversimplified a bit. The TM *can* enlist multiple threads of control (= 
connection in JTA) to the same transaction branch. That's called 
"tightly-coupled threads", and they should then be treated as one 
local transaction in the RM. The calls will look like this:

conn1.start(xid1, TMNOFLAGS);
...
conn2.start(xid1, TMJOIN);
...
conn1.end(xid1, TMSUCCESS);
...
conn2.end(xid1, TMSUCCESS);

connX.prepare(xid1);
connX.commit(xid1, false);

conn1 and conn2 must share locks and see each others changes. They 
mustn't deadlock each other. The JDBC driver can implement this in a very 
straight-forward way by using the same physical connection for both conn1 
and conn2. Note that there's only one prepare, and it can be issued using 
any connection.

The other possibility is called "loosely-coupled threads". In this case 
the calls look like this:

conn1.start(xid1, TMNOFLAGS);
...
conn2.start(xid2, TMNOFLAGS);
...
conn1.end(xid1, TMSUCCESS);
...
conn2.end(xid2, TMSUCCESS);
...
connX.prepare(xid1);
connX.prepare(xid2);
connX.commit(xid1, false);
connX.commit(xid2, false);

xid1 and xid2 can belong to the same global transaction, but different 
branches. The RM doesn't need to care both branches belong to the same 
global transactions, xid1 and xid2 can be treated just like any random 
two transactions. They can deadlock each other, and they won't see each 
others changes before commit. This can be implemented in the JDBC driver 
by using two physical connections.

So the example given earlier in this thread, with one transaction branch 
but two prepare-calls makes no sense. The RM should throw an exception 
if the TM calls start twice with the same XID, and TMJOIN flag is not 
given. One transaction branch  maps in 1:1 fashion to one RM local 
transaction.

I hope this helps...

- Heikki


Re: 2PC transaction id

From
Oliver Jowett
Date:
Heikki Linnakangas wrote:
> On Fri, 1 Jul 2005, Oliver Jowett wrote:
> 
>> Heikki Linnakangas wrote:
>>
>>> branch id: Branch Identifier. Every RM involved in the global
>>> transaction is given a *different* branch id.
>>
>>
>> Hm, I am confused then -- the XA spec definitely talks about enlisting
>> multiple RMs in a single transaction branch.
>>
>> Can you explain?
> 
> I oversimplified a bit. The TM *can* enlist multiple threads of control
> (= connection in JTA) to the same transaction branch. That's called
> "tightly-coupled threads", and they should then be treated as one local
> transaction in the RM.

Ok, I understand that case.

What I'm confused about is, for example, 3.3.1 in the DTP:XA spec:

> 3.3.1 Registration of Resource Managers
> Normally, a TM involves all associated RMs in a transaction branch. (The TM’s set of
> RM switches, described in Section 4.3 on page 21 tells the TM which RMs are
> associated with it.) The TM calls all these RMs with xa_start(), xa_end(), and
> xa_prepare (), although an RM that is not active in a branch need not participate further
> (see Section 2.3.2 on page 8). A technique to reduce overhead for infrequently-used
> RMs is discussed below.

That implies it's valid (in fact, normal!) to enlist many different RMs
in the same transaction branch. Am I interpreting that correctly?

-O


Re: 2PC transaction id

From
"Barry Lind"
Date:
>>> branch id: Branch Identifier. Every RM involved in the global
>>> transaction is given a *different* branch id.
>>
>> Hm, I am confused then -- the XA spec definitely talks about
enlisting
>> multiple RMs in a single transaction branch.
>>
>> Can you explain?
>
>I oversimplified a bit. The TM *can* enlist multiple threads of control
(=
>connection in JTA) to the same transaction branch. That's called
>"tightly-coupled threads", and they should then be treated as one
>local transaction in the RM. The calls will look like this:
>
>conn1.start(xid1, TMNOFLAGS);
>...
>conn2.start(xid1, TMJOIN);
>...
>conn1.end(xid1, TMSUCCESS);
>...
>conn2.end(xid1, TMSUCCESS);
>
>connX.prepare(xid1);
>connX.commit(xid1, false);
>
>conn1 and conn2 must share locks and see each others changes. They
>mustn't deadlock each other. The JDBC driver can implement this in a
very
>straight-forward way by using the same physical connection for both
conn1
>and conn2. Note that there's only one prepare, and it can be issued
using
>any connection.

In your example above couldn't conn1 and conn2 be running in two
different JVMs?  And thus your statement that 'the JDBC driver can
implement this in a very straight-forward way by using the same physical
connection' would not be true.  I can't see a way for two JVMs (possibly
on different client machines even) to share the same physical
connection.

--Barry





Re: 2PC transaction id

From
Heikki Linnakangas
Date:
On Fri, 1 Jul 2005, Oliver Jowett wrote:

> What I'm confused about is, for example, 3.3.1 in the DTP:XA spec:
>
>> 3.3.1 Registration of Resource Managers
>> Normally, a TM involves all associated RMs in a transaction branch. (The TMs set of
>> RM switches, described in Section 4.3 on page 21 tells the TM which RMs are
>> associated with it.) The TM calls all these RMs with xa_start(), xa_end(), and
>> xa_prepare (), although an RM that is not active in a branch need not participate further
>> (see Section 2.3.2 on page 8). A technique to reduce overhead for infrequently-used
>> RMs is discussed below.
>
> That implies it's valid (in fact, normal!) to enlist many different RMs
> in the same transaction branch. Am I interpreting that correctly?

I see. No, I don't think that's the correct interpretation, though now 
that you point it out, that paragraph is a bit confusing.

What it means, is that the TM always calls xa_start(), xa_end() and 
xa_prepare() for a RM, even if the transaction doesn't actually have any 
work to do for the RM. It has to be like that in the XA world, because the 
TM doesn't know which RMs the application really uses in the transaction.

Chapter 3.3.1 talks about dynamic registration. In that scheme, the RM 
registers itself to the TM when the application calls the RM for the first 
time in the transaction. That's an optimization to avoid the overhead of 
the start/end/prepare cycle for RMs that aren't really involved.

JTA works differently from XA on this matter. In JTA, the application 
server tells the TM which RMs are involved in the transaction, so the 
XA dynamic registration has not been included in JTA.

Disclaimer: I've never used an XA implementation, and I have only little 
experience with JTA.

- Heikki


Re: 2PC transaction id

From
Heikki Linnakangas
Date:
On Fri, 1 Jul 2005, Barry Lind wrote:

>> I oversimplified a bit. The TM *can* enlist multiple threads of control
>> (= connection in JTA) to the same transaction branch. That's called
>> "tightly-coupled threads", and they should then be treated as one
>> local transaction in the RM. The calls will look like this:
>>
>> conn1.start(xid1, TMNOFLAGS);
>> ...
>> conn2.start(xid1, TMJOIN);
>> ...
>> conn1.end(xid1, TMSUCCESS);
>> ...
>> conn2.end(xid1, TMSUCCESS);
>>
>> connX.prepare(xid1);
>> connX.commit(xid1, false);
>>
>> conn1 and conn2 must share locks and see each others changes. They
>> mustn't deadlock each other. The JDBC driver can implement this in a
> very
>> straight-forward way by using the same physical connection for both
> conn1
>> and conn2. Note that there's only one prepare, and it can be issued
> using
>> any connection.
>
> In your example above couldn't conn1 and conn2 be running in two
> different JVMs?  And thus your statement that 'the JDBC driver can
> implement this in a very straight-forward way by using the same physical
> connection' would not be true.  I can't see a way for two JVMs (possibly
> on different client machines even) to share the same physical
> connection.

I can't immediately think of a reason why they couldn't run in two 
different JVMs, but I also can't think of a reason why anyone would want 
to do that. Can you give a use case for that?

Also, it would require an application server that would support that, and 
I don't think there is any.

- Heikki


Re: 2PC transaction id

From
Heikki Linnakangas
Date:
On Fri, 1 Jul 2005, Oliver Jowett wrote:

> PS: noticed in passing: psql's help doesn't seem to know about the 2PC
> command syntax yet.

True.

Should we add support for it? 2PC is not something you normally do 
interactively...

- Heikki


Re: 2PC transaction id

From
Bruce Momjian
Date:
Heikki Linnakangas wrote:
> On Fri, 1 Jul 2005, Oliver Jowett wrote:
> 
> > PS: noticed in passing: psql's help doesn't seem to know about the 2PC
> > command syntax yet.
> 
> True.
> 
> Should we add support for it? 2PC is not something you normally do 
> interactively...

Yes, we should add psql support for it.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


Re: 2PC transaction id

From
Tom Lane
Date:
Heikki Linnakangas <hlinnaka@iki.fi> writes:
> On Fri, 1 Jul 2005, Oliver Jowett wrote:
>> PS: noticed in passing: psql's help doesn't seem to know about the 2PC
>> command syntax yet.

> True.

Really?

regression=# \h commit prepared
Command:     COMMIT PREPARED
Description: commit a transaction that was earlier prepared for two-phase commit

Syntax:
COMMIT PREPARED transaction_id

        regards, tom lane


Re: 2PC transaction id

From
Oliver Jowett
Date:
Tom Lane wrote:

> regression=# \h commit prepared
> Command:     COMMIT PREPARED
> Description: commit a transaction that was earlier prepared for two-phase commit
> 
> Syntax:
> COMMIT PREPARED transaction_id

Ah, I was looking under '\h commit', '\h prepare' etc.

-O


Re: 2PC transaction id

From
Oliver Jowett
Date:
Heikki Linnakangas wrote:
> On Fri, 1 Jul 2005, Oliver Jowett wrote:
>>
>> That implies it's valid (in fact, normal!) to enlist many different RMs
>> in the same transaction branch. Am I interpreting that correctly?
> 
> 
> I see. No, I don't think that's the correct interpretation, though now
> that you point it out, that paragraph is a bit confusing.
> 
> What it means, is that the TM always calls xa_start(), xa_end() and
> xa_prepare() for a RM, even if the transaction doesn't actually have any
> work to do for the RM. It has to be like that in the XA world, because
> the TM doesn't know which RMs the application really uses in the
> transaction.

Sorry to keep beating on this, but I still don't see where the spec says
that you must have only one RM per transaction branch.

2.2.6 says:

> 2.2.6 Transaction Branches
> A global transaction has one or more transaction branches (or branches). A branch is a
> part of the work in support of a global transaction for which the TM and the RM
> engage in a separate but coordinated transaction commitment protocol (see Section 2.3
> on page 8). Each of the RM’s internal units of work in support of a global transaction is
> part of exactly one branch.

> A global transaction might have more than one branch when, for example, the AP uses
> multiple processes or is involved in the same global transaction by multiple remote
> APs.

So it seems to me that branches are intended to allow independent
processes / APs to each have an independent set of "tightly coupled
threads" (as all work on a particular branch is tightly-coupled).
There's no mention of having only one RM per branch, which I'd expect to
see here if it was a requirement.

One implication of the second paragraph is that a single-threaded AP can
use a single transaction branch for all the work it does.

> Disclaimer: I've never used an XA implementation, and I have only little
> experience with JTA.

Mostly the same here. It'd be useful to get input from someone who's
actually written XA code..

-O


Re: 2PC transaction id

From
Kenneth Marshall
Date:
It certainly helps if you need to debug a process.

Ken

On Fri, Jul 01, 2005 at 09:06:03PM +0300, Heikki Linnakangas wrote:
> On Fri, 1 Jul 2005, Oliver Jowett wrote:
> 
> >PS: noticed in passing: psql's help doesn't seem to know about the 2PC
> >command syntax yet.
> 
> True.
> 
> Should we add support for it? 2PC is not something you normally do 
> interactively...
> 
> - Heikki
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 9: In versions below 8.0, the planner will ignore your desire to
>       choose an index scan if your joining column's datatypes do not
>       match


Re: 2PC transaction id

From
Heikki Linnakangas
Date:
On Sat, 2 Jul 2005, Oliver Jowett wrote:

> Sorry to keep beating on this, but I still don't see where the spec says
> that you must have only one RM per transaction branch.

Sure, it's important to get this right.

> 2.2.6 says:
>
>> 2.2.6 Transaction Branches
>> A global transaction has one or more transaction branches (or branches). A branch is a
>> part of the work in support of a global transaction for which the TM and the RM
>> engage in a separate but coordinated transaction commitment protocol (see Section 2.3
>> on page 8). Each of the RMs internal units of work in support of a global transaction is
>> part of exactly one branch.
>
>> A global transaction might have more than one branch when, for example, the AP uses
>> multiple processes or is involved in the same global transaction by multiple remote
>> APs.
>
> So it seems to me that branches are intended to allow independent
> processes / APs to each have an independent set of "tightly coupled
> threads" (as all work on a particular branch is tightly-coupled).
> There's no mention of having only one RM per branch, which I'd expect to
> see here if it was a requirement.

They should have been explicit about it, I agree.

The key is the clause "A branch is a part of the work in support of a 
global transaction for which the TM and the RM engage in a separate but 
coordinated transaction commitment protocol". That means that for each 
branch, there's exactly one call to prepare and commit. If you have two 
RMs, you need two prepare/commit calls, so you need two branches.

> One implication of the second paragraph is that a single-threaded AP can
> use a single transaction branch for all the work it does.

No, that paragraph says "for example". The third example is the case where 
you have more than one RM :).

As further, non-authoritative, evidence, see this DevX article on JTA:

http://archive.devx.com/java/free/articles/dd_jta/jta-2.asp

Search for "branch" in that article. It says explicitly "Requests to three 
different RDBMSs, therefore, require three transaction branches."

- Heikki