You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by ludovic orban <lu...@gmail.com> on 2006/05/10 22:17:47 UTC

XA_RDONLY optimization - question

Hi,

I carefully read Mike Spille's XA Exposed articles but there was
something I could never properly understand. I hope somebody here will
be able and kind enough to help me understand what I missed.


The question I have lies in "The 1PC Optimization..." paragraph of XA
Exposed - Part II
(http://jroller.com/page/pyrasun?entry=xa_exposed_part_ii_schwartz).

Quoting Mike :


...only 1 XAResource has actually done any useful work. Here are some
reasons why this can happen:

   * Only one transaction ever got enlisted. There are a number of
combinations of configuration and/or application logic that can lead
to this condition.
   * Every resource but one returned XA_RDONLY from its prepare() call

The 1PC optimization itself is very simple: the Transaction Manager
skips writing a "Committing..." record, it skips the prepare() call,
and calls commit() on the lone XA Resource directly.


Now I believe that the second point Mike enumerated (Every resource but
one returned XA_RDONLY from its prepare() call) is not consistent with
the ending sentence (writing a "Committing..." record, ==> it skips
the prepare() call <==). How can you trigger 1PC with the XA_RDONLY
vote ? You will only know the result of that vote after the prepare
call and then it's too late to commit with the 1PC optimization ! The
best you can do is skip the COMMITTING log record force while still
calling commit with 1PC boolean flag set to false on the sole resource
that returned XA_OK.

You end up with 2 disk forces in that case instead of the single one
you would get with a plain 1PC optimization.


I'd really appreciate if anyone could comment on this.

Thank you in advance,
Ludovic

Re: XA_RDONLY optimization - question

Posted by David Jencks <da...@yahoo.com>.
On May 10, 2006, at 10:47 PM, ludovic orban wrote:

> David,
>
>> 1. there's only one resource in the transaction.  Well, you can just
>> call 1pc commit on it.  As a special case, if there are lots of
>> resources, but all but the last one says it's read-only, you can just
>> call 1pc commit on the last one (skipping prepare).  I think it's
>> sort of obvious this works, and doesn't introduce any risks of data
>> loss.
>
> I agree on this but running the prepare calls in parallel voids the
> special case of the last resource returning read-only.
>
>
>> 2. if your last resource only supports 1pc (it's not xa) some people
>> think you can just call commit on it, and then write the prepare
>> record for the other participants: you use the result of this 1pc
>> commit to decide whether to proceed or roll back the other
>> participants.   A little thought shows that the time between the
>> completion of the 1pc commit and writing the prepare record to the
>> log is vulnerable and can result in inconsistency.  (many people
>> don't seem to realize this).
>
> This is what Mike calls 'Last Resource Gambit'. It's main usage is to
> allow non-XA resources to participate in 2PC, it has very little to do
> with transaction speed optimization. I personally refuse to use that
> trick since it's not ACID.
>
>> However, there's a trick that can make
>> it work :-)  If you store the transaction log in the 1pc resource,
>> and only do the commit as a part of writing the prepare record to the
>> log (ignoring the 1pc commit call directly to the resource) then the
>> semantics work out properly.  AFAIK Jeremy Boynes thought this up,
>> and I've implemented it in geronimo, but so far there is no testing
>> of it.
>
> BEA implemented this in Weblogic 9 and called it 'Logging Last
> Resource' (http://edocs.bea.com/wls/docs90/jta/llr.html).
> The good points of this technique are that you can use a non-XA
> resource in 2PC while staying 100% ACID and you get a slight
> performance boost if you only use 2 resources in the transaction.
> The bad points are that if you use more than 2 resources this method
> is slower than using a file based tx log and also it messes up a bit
> your DB schema since you have to create some tx log table(s) in the
> same DB schema. It also can only work if the resource is a database.
>
> So if I properly deciphered your email, the XA_RDONLY vote is pretty
> much useless since it only allows a 1PC optimization on the last
> resource to be prepared and only if your don't run prepare calls in
> parallel.
>
> Am I right ?

As far as I can tell, yes :-)

thanks
david jencks

>
> Thank you,
> Ludovic


Re: XA_RDONLY optimization - question

Posted by ludovic orban <lu...@gmail.com>.
David,

> 1. there's only one resource in the transaction.  Well, you can just
> call 1pc commit on it.  As a special case, if there are lots of
> resources, but all but the last one says it's read-only, you can just
> call 1pc commit on the last one (skipping prepare).  I think it's
> sort of obvious this works, and doesn't introduce any risks of data
> loss.

I agree on this but running the prepare calls in parallel voids the
special case of the last resource returning read-only.


> 2. if your last resource only supports 1pc (it's not xa) some people
> think you can just call commit on it, and then write the prepare
> record for the other participants: you use the result of this 1pc
> commit to decide whether to proceed or roll back the other
> participants.   A little thought shows that the time between the
> completion of the 1pc commit and writing the prepare record to the
> log is vulnerable and can result in inconsistency.  (many people
> don't seem to realize this).

This is what Mike calls 'Last Resource Gambit'. It's main usage is to
allow non-XA resources to participate in 2PC, it has very little to do
with transaction speed optimization. I personally refuse to use that
trick since it's not ACID.

> However, there's a trick that can make
> it work :-)  If you store the transaction log in the 1pc resource,
> and only do the commit as a part of writing the prepare record to the
> log (ignoring the 1pc commit call directly to the resource) then the
> semantics work out properly.  AFAIK Jeremy Boynes thought this up,
> and I've implemented it in geronimo, but so far there is no testing
> of it.

BEA implemented this in Weblogic 9 and called it 'Logging Last
Resource' (http://edocs.bea.com/wls/docs90/jta/llr.html).
The good points of this technique are that you can use a non-XA
resource in 2PC while staying 100% ACID and you get a slight
performance boost if you only use 2 resources in the transaction.
The bad points are that if you use more than 2 resources this method
is slower than using a file based tx log and also it messes up a bit
your DB schema since you have to create some tx log table(s) in the
same DB schema. It also can only work if the resource is a database.

So if I properly deciphered your email, the XA_RDONLY vote is pretty
much useless since it only allows a 1PC optimization on the last
resource to be prepared and only if your don't run prepare calls in
parallel.

Am I right ?

Thank you,
Ludovic

Re: XA_RDONLY optimization - question

Posted by David Jencks <da...@yahoo.com>.
On May 10, 2006, at 1:17 PM, ludovic orban wrote:

> Hi,
>
> I carefully read Mike Spille's XA Exposed articles but there was
> something I could never properly understand. I hope somebody here will
> be able and kind enough to help me understand what I missed.
>
>
> The question I have lies in "The 1PC Optimization..." paragraph of XA
> Exposed - Part II
> (http://jroller.com/page/pyrasun?entry=xa_exposed_part_ii_schwartz).
>
> Quoting Mike :
>
>
> ...only 1 XAResource has actually done any useful work. Here are some
> reasons why this can happen:
>
>   * Only one transaction ever got enlisted. There are a number of
> combinations of configuration and/or application logic that can lead
> to this condition.
>   * Every resource but one returned XA_RDONLY from its prepare() call
>
> The 1PC optimization itself is very simple: the Transaction Manager
> skips writing a "Committing..." record, it skips the prepare() call,
> and calls commit() on the lone XA Resource directly.
>
>
> Now I believe that the second point Mike enumerated (Every resource  
> but
> one returned XA_RDONLY from its prepare() call) is not consistent with
> the ending sentence (writing a "Committing..." record, ==> it skips
> the prepare() call <==). How can you trigger 1PC with the XA_RDONLY
> vote ? You will only know the result of that vote after the prepare
> call and then it's too late to commit with the 1PC optimization ! The
> best you can do is skip the COMMITTING log record force while still
> calling commit with 1PC boolean flag set to false on the sole resource
> that returned XA_OK.
>
> You end up with 2 disk forces in that case instead of the single one
> you would get with a plain 1PC optimization.
>
>
> I'd really appreciate if anyone could comment on this.


I don't think mike explained it very well, and there are 2 things  
called 1pc optimization.  I haven't checked what he wrote recently,  
but unless you are misquoting him I agree with you that there's a  
contradiction.  Here's my attempt to explain the 2 scenarios:

1. there's only one resource in the transaction.  Well, you can just  
call 1pc commit on it.  As a special case, if there are lots of  
resources, but all but the last one says it's read-only, you can just  
call 1pc commit on the last one (skipping prepare).  I think it's  
sort of obvious this works, and doesn't introduce any risks of data  
loss.

2. if your last resource only supports 1pc (it's not xa) some people  
think you can just call commit on it, and then write the prepare  
record for the other participants: you use the result of this 1pc  
commit to decide whether to proceed or roll back the other  
participants.   A little thought shows that the time between the  
completion of the 1pc commit and writing the prepare record to the  
log is vulnerable and can result in inconsistency.  (many people  
don't seem to realize this).  However, there's a trick that can make  
it work :-)  If you store the transaction log in the 1pc resource,  
and only do the commit as a part of writing the prepare record to the  
log (ignoring the 1pc commit call directly to the resource) then the  
semantics work out properly.  AFAIK Jeremy Boynes thought this up,  
and I've implemented it in geronimo, but so far there is no testing  
of it.

Hope this helps
david jencks



>
> Thank you in advance,
> Ludovic