Thread: Re: Postgres XA support

Re: Postgres XA support

From
Kris Jurka
Date:
Ludovic Orban wrote:

> I rencently found this thread on PotgreSQL's forum:
> http://archives.postgresql.org/pgsql-jdbc/2006-04/msg00150.php
> and I just wanted to let you know that calling Connection.close()
> before or after the commit is the transaction manager's job or more
> precisely the XA connection pool's job.

So you're suggesting that the code example here is incorrect and it must
call commit before close?  It really seems like a transaction ought to
correcty wrap the connection open/close which is the fix that I put in.

http://archives.postgresql.org/pgsql-jdbc/2006-04/msg00149.php

> I'd like to know a bit more about Postgres' XA support before testing
> it (to add it to my support list:
> http://www.bitronix.be/Btm/DatabasesXASupportEvaluation#postgres) and
> I'd be happy if you could brielfy tell me how you think it's working.

Honestly, I have no idea.  As a maintainer I occasionally have to
write/review code that I don't know much about and XA is one of those.
Asking on the jdbc list (cced) is the best place to get information as
the authors and users of the XA code can attest to its support much
better than I can.  I hear it works with Orion and with a small patch
Weblogic.  My limited testing showed it worked with Simple-JTA.

Kris Jurka

Re: Postgres XA support

From
Kris Jurka
Date:
Ludovic Orban wrote:
>  From the comments I saw in the source, transaction interleaving, join
> and suspend/resume are still not supported and forget is still
> unimplemented. This means you cannot mix local and global
> transactions, cannot support EJBs with REQUIRES_NEW CMT declaration
> and can get into troubles during crash recovery.
>
> I think it was Michael Allman that said the engine wasn't able to
> properly support XA in Aug 2005 and unfortunately it seems that things
> haven't changed much since then.
>
> I'm afraid you still have some work to do on the engine before you can
> implement XA in JDBC.

Well there are two perspectives on this.  If you need a way of
implementing multi-resource transactions, than the simple two phase
commit approach implemented in postgresql is adequate.  If full XA
compliance is required then postgresql comes up far short.  Yes, backend
development has stalled on this.  Backend developers were not aware of
the full XA requirements and when informed said, "We implemented all
this two phase stuff and now you're telling us it's inadequate!"  So
they've moved on and the ability to do things like transaction
interleaving are very complicated given the postgresql backend model, so
I wouldn't hold my breath on things changing anytime soon.

Kris Jurka


Re: Postgres XA support

From
Heikki Linnakangas
Date:
Kris Jurka wrote:
> Ludovic Orban wrote:
>
>> I'd like to know a bit more about Postgres' XA support before testing
>> it (to add it to my support list:
>> http://www.bitronix.be/Btm/DatabasesXASupportEvaluation#postgres) and
>> I'd be happy if you could brielfy tell me how you think it's working.

We had off-list discussions about this some time ago, as you probably
remember. I'd be glad to tell you more if you have any further questions.

> Asking on the jdbc list (cced) is the best place to get information as
> the authors and users of the XA code can attest to its support much
> better than I can.

Agreed.

 >  I hear it works with Orion and with a small patch
> Weblogic.  My limited testing showed it worked with Simple-JTA.

It's very important that we have a wide range of XA test cases in test
suite, because we can't test with every possible transaction manager
implementation whenever we change something.

It would be nice to collect sample configurations of application servers
/ transaction managers as people get the driver to work with them.

I personally used JOnAS for testing. We should start to collect a list
of known working configurations.

* JOnAS
* WebLogic (with patch; I hope we can get it applied soon)
* Orion
* Simple JTA
* Geronimo (with patch, see the recent thread about auto commit problems)

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: Postgres XA support

From
Heikki Linnakangas
Date:
> Ludovic Orban wrote:
>>  From the comments I saw in the source, transaction interleaving, join
>> and suspend/resume are still not supported and forget is still
>> unimplemented. This means you cannot mix local and global
>> transactions, cannot support EJBs with REQUIRES_NEW CMT declaration
>> and can get into troubles during crash recovery.

Can you clarify how that can get you into trouble during crash recovery?

We had a discussion about this earlier, and it seems I never replied to
your latest comment on the EJB REQUIRES_NEW support. Let me do that now:

Ludovic Orban wrote:
 > Heikki Linnakangas wrote:
 >> Ludovic Orban wrote:
 >>> Appart from that, suspend/resume is mandatory to implement CMT
 >>> REQUIRES_NEW semantics of the EJB servers.
 >>
 >> Why? Can't you just open a new connection on a REQUIRES_NEW method
 >> call?
 >
 > REQUIRES_NEW requires to start a brand new transaction for the
 > duration of the call. The only way to do this is to sak the TM to
 > suspend the current transaction, start the new one and when it's
 > finished resume the first one.
 >
 > Since a transaction is bound to a thread the is no way to do this
 > other than suspend/resume.

AFAICS, the transaction manager can simply keep the original connection
associated with the original transaction, and open a new connection
associated with the new transaction when needed. Can you give a specific
example scenario that's impossible to implement without suspend/resume
support?

>> I think it was Michael Allman that said the engine wasn't able to
>> properly support XA in Aug 2005 and unfortunately it seems that things
>> haven't changed much since then.
>>
>> I'm afraid you still have some work to do on the engine before you can
>> implement XA in JDBC.
>
> Well there are two perspectives on this.  If you need a way of
> implementing multi-resource transactions, than the simple two phase
> commit approach implemented in postgresql is adequate.  If full XA
> compliance is required then postgresql comes up far short.  Yes, backend
> development has stalled on this.  Backend developers were not aware of
> the full XA requirements and when informed said, "We implemented all
> this two phase stuff and now you're telling us it's inadequate!"  So
> they've moved on and the ability to do things like transaction
> interleaving are very complicated given the postgresql backend model, so
> I wouldn't hold my breath on things changing anytime soon.

I don't see much value in implementing the full XA spec. What we have
now is enough to implement distributed transactions reliably, and that's
what XA is all about.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: Postgres XA support

From
Heikki Linnakangas
Date:
Ludovic Orban wrote:
>>
>> I personally used JOnAS for testing. We should start to collect a list
>> of known working configurations.
>>
>> * JOnAS
>> * WebLogic (with patch; I hope we can get it applied soon)
>> * Orion
>> * Simple JTA
>> * Geronimo (with patch, see the recent thread about auto commit problems)
>
> I agree but what do you call 'working configuration' ?

Good question :).

> Due to the current limitations you could get simple cases working
> while at the same time excluding some very important ones because
> they're unsupported.

Agreed. It'd be nice to have a test application, packaged in an EAR for
example, that would exercise all the unusual scenarios including
recovery. It'd be extremely useful for testing JTA implementations as
well. Sun might actually have a test kit like that, but they're probably
proprietary and expensive.

> I'm not 100% sure about this but the fact that you cannot mix local
> and global transactions will prevent Hibernate applications to work
> when built with JTA. There are many cases where these features that
> look not that important at first are quite critical.

Interesting. I don't know Hibernate very well, but I'd assume that it's
  just using the UserTransaction et al. APIs, and shouldn't look any
different than other applications to the JDBC driver.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: Postgres XA support

From
Heikki Linnakangas
Date:
Ludovic Orban wrote:
>> >>  From the comments I saw in the source, transaction interleaving, join
>> >> and suspend/resume are still not supported and forget is still
>> >> unimplemented. This means you cannot mix local and global
>> >> transactions, cannot support EJBs with REQUIRES_NEW CMT declaration
>> >> and can get into troubles during crash recovery.
>>
>> Can you clarify how that can get you into trouble during crash recovery?
>
> Simply because XAResource.forget() is not implemented. You won't
> exactly be into trouble because of this but extra manual work might be
> needed to check that an after-crash recovery succeeded.

Right, this comes down to the definition of heuristic commit/abort. The
way I read the specs, a heuristic commit/rollback means that the
resource adapter has independently decided to commit or rollback a
transaction. A typical implementation would be to roll back prepared
transactions after a timeout if the connection to the TM is lost.

The way you read the specs is that when the administrator manually
commits or aborts a transaction, that's also a heuristic commit/abort.

The JTA spec doesn't go into details, but the XA spec (Section 2.3.3)
says: "Some RMs may employ heuristic decision-making: an RM that has
prepared to commit a transaction branch may decide to commit or roll
back its work independently of the TM."

Section 7.3 explicitly lists "Heuristics" as an optional feature.

I don't think the XA spec supports the view that manual commit or
rollback is considered a heuristic decision. The administrator better
not mess with in-doubt transactions. If she does, the safe way to do it
is to first take the TM and all resource managers offline, manually
finish all the transactions in the TM, and then manually finish all the
transactions in the RMs.

BTW: If we wanted to report manual commits/aborts as heuristic
decisions, that would be possible with some minor changes to the
backend. We would need to add an option to the COMMIT/ROLLBACK PREPARED
commands saying it's a heuristic decision, and have those commands
insert a row to a table. forget would then delete the row. But I don't
think we should do that.

 > You will have the same doubts when reconciliating the TM logs with the
 > DB logs after a heuristic decision happened.

Heuristic decisions don't happen, because PostgreSQL doesn't do them.
(per my interpretation of the spec)

> Opening a new connection as you describe would probably work. It is
> then the responsibility of the EJB container to implement REQUIRES_NEW
> in this way instead of using the TM's suspend service but I don't know
> of any container that implements REQUIRES_NEW without calling suspend
> on the TM.

Oh, the container can call TM's suspend service. But that doesn't mean
that the TM has to call suspend on the resource managers. In fact, if
you have a non-distributed transaction, with a non-XA enabled JDBC
driver, there isn't a suspend-method to call.

To turn the question around: Do you know of a container/app.server that
*does* require suspend/resume support from the XADataSource
implementation to support REQUIRES_NEW?

>> I don't see much value in implementing the full XA spec. What we have
>> now is enough to implement distributed transactions reliably, and that's
>> what XA is all about.
>
> I disagree. There are some parts of the XA spec that might well be
> considered as optional but suspend/resume, ability to mix local/global
> transactions and recovery can't be. Yes you can run distributed
> transactions reliably but with so many restrictions that it's of no
> use.

Do you have a use case in mind that's not currently possible? I'd like
to hear about it so we can try to make it work.

Recovery definitely isn't optional, and it's required for reliable
operation. Suspend/resume is a required part of the spec, but it isn't
required for reliable operation and it's not required in practice
because app. servers can work around it.

What do you mean by mixing local/global transactions?

> Please don't get me wrong here. I'm not bashing Postgres nor your work
> in any way I'm just saying that it's still lacking features to make it
> really usable with XA transactions. Mysql and Ingres fall in exactly
> the same category: they provide incomplete (even worse, sometimes
> incorrect) XA support as well.

I believe there's three reasons most RM implementations don't implement
suspend/resume or transaction interleaving:

1. They don't let you to do anything you can't do without
2. It would be a very invasive change to add them to the underlaying
architecture and wire protocol of an existing DBMS
3. Because of 1, and the lack of support in other DBMS's, app servers
don't use them, and provide ways to work around them, making the
features optional, de facto.

An incorrect implementation is indeed much worse than an incomplete
implementation. Some DBMS vendors claim XA support even with incomplete
or broken implementations. We've tried to be very up-front of the
limitations of the PostgreSQL driver.

No offense taken :). It's important to discuss these things if there's
any doubts.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: Postgres XA support

From
Heikki Linnakangas
Date:
Ludovic Orban wrote:

>>  > You will have the same doubts when reconciliating the TM logs with the
>>  > DB logs after a heuristic decision happened.
>>
>> Heuristic decisions don't happen, because PostgreSQL doesn't do them.
>> (per my interpretation of the spec)
>
> Once again: manually logging into the DB after the TM crashed and
> manually calling COMMIT/ROLLBACK PREPARED is a heuristic IMU.

Well, I haven't found anything in the XA spec or by googling that
explicitly says whether manually finishing a transaction counts as a
heuristic decision or not. The XA spec refers to the OSI DTP standard.
Perhaps that would shed some light to the issue, however I don't have
access to it. Without an authoritative source, there's no point in arguing.

>> To turn the question around: Do you know of a container/app.server that
>> *does* require suspend/resume support from the XADataSource
>> implementation to support REQUIRES_NEW?
>
> OpenEJB/Geronimo:
>
http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/transaction/TxRequiresNew.java?view=markup

>
>
> I'm pretty sure that Weblogic, Orion and JBoss work the same as well
> but that was a long time ago so I'd need to double-check.
>
> Hibernate also uses suspend/resume for some of its PK generation stategies:
> http://www.hibernate.org/hib_docs/v3/api/org/hibernate/id/MultipleHiLoPerTableGenerator.html
>
> http://www.hibernate.org/hib_docs/v3/api/org/hibernate/id/TableGenerator.html

You seem to be confusing the suspend/resume facility of the Transaction
Manager, and suspend/resume on a resource adapter. All of the above
examples are calls to the TM's suspend method. A call to
TransactionManager.suspend doesn't imply a call to XAResource.suspend.

If you look at the implementation of that in Geronimo, for example:


http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java?view=markup

you will see that it simply removes the current transaction from a
HashMap that keeps track of which transactions are associated with which
threads. AFAICS, it does *not* call XAResource.suspend on the enlisted
resources.

I just downloaded Geronimo, and modified the Bank sample application to
call a REQUIRES_NEW bean method within another transaction. It seems to
work just fine, it opens a new connection and runs the REQUIRES_NEW
transaction with that. I can send you the code and/or logs if you want
to try it yourself.

>> What do you mean by mixing local/global transactions?
>
> This is a common way of using a XA connection pool that mixes both
> local and global transactions:
>
> c = ds.getConnection()
> c.executeUpdate("UPDATE 1")
> c.setAutoCommit(false)
> c.executeUpdate("UPDATE 2")
> tm.begin()
> c.executeUpdate("UPDATE 3")
> tm.rollback()
> c.commit()
>
> UPDATE 1 is done in a local transaction while in autocommit mode, it
> is committed.
> UPDATE 2 is done in a local transaction manually committed, it is
> committed.
> UPDATE 3 is done in a global transaction which is rolled back, it is
> rolled back.
>
> Does PostgreSQL supports this ? If not, applications using Hibernate
> might not work as it runs queries in local transaction mode on its own
> during startup.

Hmm, we should be supporting that, but it might not work with the
current released version given the bug with setAutoCommit reported by
Allan Saddi recently. We should add a test case for that...

> It's also common even with applications not using Hibernate to execute
> statements in local and then in global mode with the same connection.

Really? In my experience, you don't write applications that directly
interact with the TM. You leave that to the application server, and app
servers just always start a XA transaction because it doesn't know
beforehand if a transaction is going to be global or local.

>> I believe there's three reasons most RM implementations don't implement
>> suspend/resume or transaction interleaving:
>
> I only know two implementations not supporting these features:
> Postgres and Mysql. Oracle and Sybase have some limitations in the way
> transaction interleaving can be used but it more or less works as it
> should nevertheless.

I believe the limitations in Oracle and Sybase are the same as in
PostgreSQL: you can't do transaction interleaving. Or do they support
some limited kind of transaction interleaving that we don't? If they do,
  we could see what it would take for us to support those scenarios as well.

DB2 had problems when I tested it, search the archives for details. I
wonder how MS SQL Server works?

>> 1. They don't let you to do anything you can't do without
>> 2. It would be a very invasive change to add them to the underlaying
>> architecture and wire protocol of an existing DBMS
>> 3. Because of 1, and the lack of support in other DBMS's, app servers
>> don't use them, and provide ways to work around them, making the
>> features optional, de facto.
>
> For 1, not having them seriously lowers the flexibility given to the
> application programmer.

By "Application programmer" you're meaning the developer of the
transaction manager, right? People developing normal applications that
just utilize global transactions don't need to care about all this.

> For 2, if XA was that easy to implement it would be much more widely
> implemented, don't you think ? How many open source DB supports XA ?
> Close to zero.

Sure, if it was easy, we might as well do it to tick the "fully XA
compatible" box. What's your point?

> For 3, I don't know as all databases that I've seen used with XA
> transaction properly support those features.
> I've also never seen a transaction manager implementing suspend/resume
> by not using the XA facilities. Do you know one that does ?

See Geronimo example above. I haven't looked at any other TMs.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: Postgres XA support

From
"Ludovic Orban"
Date:
Heikki,

> It's very important that we have a wide range of XA test cases in test
> suite, because we can't test with every possible transaction manager
> implementation whenever we change something.
>
> It would be nice to collect sample configurations of application servers
> / transaction managers as people get the driver to work with them.
>
> I personally used JOnAS for testing. We should start to collect a list
> of known working configurations.
>
> * JOnAS
> * WebLogic (with patch; I hope we can get it applied soon)
> * Orion
> * Simple JTA
> * Geronimo (with patch, see the recent thread about auto commit problems)

I agree but what do you call 'working configuration' ?

Due to the current limitations you could get simple cases working
while at the same time excluding some very important ones because
they're unsupported.

I'm not 100% sure about this but the fact that you cannot mix local
and global transactions will prevent Hibernate applications to work
when built with JTA. There are many cases where these features that
look not that important at first are quite critical.

Ludovic

Re: Postgres XA support

From
"Ludovic Orban"
Date:
> >>  From the comments I saw in the source, transaction interleaving, join
> >> and suspend/resume are still not supported and forget is still
> >> unimplemented. This means you cannot mix local and global
> >> transactions, cannot support EJBs with REQUIRES_NEW CMT declaration
> >> and can get into troubles during crash recovery.
>
> Can you clarify how that can get you into trouble during crash recovery?

Simply because XAResource.forget() is not implemented. You won't
exactly be into trouble because of this but extra manual work might be
needed to check that an after-crash recovery succeeded.

You will have the same doubts when reconciliating the TM logs with the
DB logs after a heuristic decision happened.


> We had a discussion about this earlier, and it seems I never replied to
> your latest comment on the EJB REQUIRES_NEW support. Let me do that now:
>
> AFAICS, the transaction manager can simply keep the original connection
> associated with the original transaction, and open a new connection
> associated with the new transaction when needed. Can you give a specific
> example scenario that's impossible to implement without suspend/resume
> support?

Opening a new connection as you describe would probably work. It is
then the responsibility of the EJB container to implement REQUIRES_NEW
in this way instead of using the TM's suspend service but I don't know
of any container that implements REQUIRES_NEW without calling suspend
on the TM.


> I don't see much value in implementing the full XA spec. What we have
> now is enough to implement distributed transactions reliably, and that's
> what XA is all about.

I disagree. There are some parts of the XA spec that might well be
considered as optional but suspend/resume, ability to mix local/global
transactions and recovery can't be. Yes you can run distributed
transactions reliably but with so many restrictions that it's of no
use.

Please don't get me wrong here. I'm not bashing Postgres nor your work
in any way I'm just saying that it's still lacking features to make it
really usable with XA transactions. Mysql and Ingres fall in exactly
the same category: they provide incomplete (even worse, sometimes
incorrect) XA support as well.

Ludovic

Re: Postgres XA support

From
"Ludovic Orban"
Date:
Heikki,

> Right, this comes down to the definition of heuristic commit/abort. The
> way I read the specs, a heuristic commit/rollback means that the
> resource adapter has independently decided to commit or rollback a
> transaction. A typical implementation would be to roll back prepared
> transactions after a timeout if the connection to the TM is lost.
>
> The way you read the specs is that when the administrator manually
> commits or aborts a transaction, that's also a heuristic commit/abort.

The way I understand heuristics is as follows:
any decision not taken by the transaction manager is a heuristic
decision. I can be a timeout or an administrator manually terminating
the transaction or whatever else.


> The JTA spec doesn't go into details, but the XA spec (Section 2.3.3)
> says: "Some RMs may employ heuristic decision-making: an RM that has
> prepared to commit a transaction branch may decide to commit or roll
> back its work independently of the TM."
>
> Section 7.3 explicitly lists "Heuristics" as an optional feature.

Actually it is section 7.2 but you're right, it seems that resources
are not mandated to support heuristic decistions.


> I don't think the XA spec supports the view that manual commit or
> rollback is considered a heuristic decision. The administrator better
> not mess with in-doubt transactions. If she does, the safe way to do it
> is to first take the TM and all resource managers offline, manually
> finish all the transactions in the TM, and then manually finish all the
> transactions in the RMs.

I think this is where you are wrong as per my understanding of
heuristics. Why would there be a difference between a heuristic and a
manual intervention ?

A heuristic decision should be taken when it's been decided that
global consistency is less important that resource availability. It is
a process that should only be used at last resort, I agree but it can
make difference between life and death, when you prefer running with a
degraded service than with no service at all.

In the end, the TM will have to reconcile its log with the resource's
state and report potential inconsistencies due to decisions not taken
by itself. Why wouldn't it report an inconsistency created by a human
intervention ?


> BTW: If we wanted to report manual commits/aborts as heuristic
> decisions, that would be possible with some minor changes to the
> backend. We would need to add an option to the COMMIT/ROLLBACK PREPARED
> commands saying it's a heuristic decision, and have those commands
> insert a row to a table. forget would then delete the row. But I don't
> think we should do that.

That's one way of doing it but you can refine it a bit.


>  > You will have the same doubts when reconciliating the TM logs with the
>  > DB logs after a heuristic decision happened.
>
> Heuristic decisions don't happen, because PostgreSQL doesn't do them.
> (per my interpretation of the spec)

Once again: manually logging into the DB after the TM crashed and
manually calling COMMIT/ROLLBACK PREPARED is a heuristic IMU.


> > Opening a new connection as you describe would probably work. It is
> > then the responsibility of the EJB container to implement REQUIRES_NEW
> > in this way instead of using the TM's suspend service but I don't know
> > of any container that implements REQUIRES_NEW without calling suspend
> > on the TM.
>
> Oh, the container can call TM's suspend service. But that doesn't mean
> that the TM has to call suspend on the resource managers. In fact, if
> you have a non-distributed transaction, with a non-XA enabled JDBC
> driver, there isn't a suspend-method to call.
>
> To turn the question around: Do you know of a container/app.server that
> *does* require suspend/resume support from the XADataSource
> implementation to support REQUIRES_NEW?

OpenEJB/Geronimo:

http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/transaction/TxRequiresNew.java?view=markup

I'm pretty sure that Weblogic, Orion and JBoss work the same as well
but that was a long time ago so I'd need to double-check.

Hibernate also uses suspend/resume for some of its PK generation stategies:
http://www.hibernate.org/hib_docs/v3/api/org/hibernate/id/MultipleHiLoPerTableGenerator.html
http://www.hibernate.org/hib_docs/v3/api/org/hibernate/id/TableGenerator.html


> Do you have a use case in mind that's not currently possible? I'd like
> to hear about it so we can try to make it work.
>
> Recovery definitely isn't optional, and it's required for reliable
> operation. Suspend/resume is a required part of the spec, but it isn't
> required for reliable operation and it's not required in practice
> because app. servers can work around it.
>
> What do you mean by mixing local/global transactions?

This is a common way of using a XA connection pool that mixes both
local and global transactions:

c = ds.getConnection()
c.executeUpdate("UPDATE 1")
c.setAutoCommit(false)
c.executeUpdate("UPDATE 2")
tm.begin()
c.executeUpdate("UPDATE 3")
tm.rollback()
c.commit()

UPDATE 1 is done in a local transaction while in autocommit mode, it
is committed.
UPDATE 2 is done in a local transaction manually committed, it is committed.
UPDATE 3 is done in a global transaction which is rolled back, it is
rolled back.

Does PostgreSQL supports this ? If not, applications using Hibernate
might not work as it runs queries in local transaction mode on its own
during startup.

It's also common even with applications not using Hibernate to execute
statements in local and then in global mode with the same connection.


> I believe there's three reasons most RM implementations don't implement
> suspend/resume or transaction interleaving:

I only know two implementations not supporting these features:
Postgres and Mysql. Oracle and Sybase have some limitations in the way
transaction interleaving can be used but it more or less works as it
should nevertheless.


> 1. They don't let you to do anything you can't do without
> 2. It would be a very invasive change to add them to the underlaying
> architecture and wire protocol of an existing DBMS
> 3. Because of 1, and the lack of support in other DBMS's, app servers
> don't use them, and provide ways to work around them, making the
> features optional, de facto.

For 1, not having them seriously lowers the flexibility given to the
application programmer.
For 2, if XA was that easy to implement it would be much more widely
implemented, don't you think ? How many open source DB supports XA ?
Close to zero.
For 3, I don't know as all databases that I've seen used with XA
transaction properly support those features.
I've also never seen a transaction manager implementing suspend/resume
by not using the XA facilities. Do you know one that does ?


> An incorrect implementation is indeed much worse than an incomplete
> implementation. Some DBMS vendors claim XA support even with incomplete
> or broken implementations. We've tried to be very up-front of the
> limitations of the PostgreSQL driver.
>
> No offense taken :). It's important to discuss these things if there's
> any doubts.

Agreed.


Ludovic

Re: Postgres XA support

From
"Ludovic Orban"
Date:
Heikki,

> Well, I haven't found anything in the XA spec or by googling that
> explicitly says whether manually finishing a transaction counts as a
> heuristic decision or not. The XA spec refers to the OSI DTP standard.
> Perhaps that would shed some light to the issue, however I don't have
> access to it. Without an authoritative source, there's no point in arguing.

How would you call it then ? You will never be able to see this 'OSI
DTP standard' unless you're going to pay for the specs so you
shouldn't count on it.

My question stands: why would you make a difference between a manual
intervention or an automated intervention of the engine ? The end
result is the same: the transaction has been terminated ultimately
without the transaction manager's knowledge.

You could just write in the Postgres documentation 'never call
COMMIT/ROLLBACK PREPARED on in-doubts transactions as heuristics are
not supported' but that's just postponing (and documenting which is
nice) the problem. It is not very realistic to have a resource on
production that does not support heuristics.


> You seem to be confusing the suspend/resume facility of the Transaction
> Manager, and suspend/resume on a resource adapter. All of the above
> examples are calls to the TM's suspend method. A call to
> TransactionManager.suspend doesn't imply a call to XAResource.suspend.
>
> If you look at the implementation of that in Geronimo, for example:
>
>
http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java?view=markup
>
> you will see that it simply removes the current transaction from a
> HashMap that keeps track of which transactions are associated with which
> threads. AFAICS, it does *not* call XAResource.suspend on the enlisted
> resources.
>
> I just downloaded Geronimo, and modified the Bank sample application to
> call a REQUIRES_NEW bean method within another transaction. It seems to
> work just fine, it opens a new connection and runs the REQUIRES_NEW
> transaction with that. I can send you the code and/or logs if you want
> to try it yourself.

Actually I ran some tests against Weblogic and Atomikos and I must say
that none of them are using suspend/resume facilities of the RMs to
implement transaction suspension. You were entirely right.

Depending on the enlistment implementation (agressive or gentle) the
TM will use end(TMSUCCESS) and start(TMJOIN) or silently won't allow a
connection to hosts two global transactions.

Weblogic uses an agressive policy while Atomikos, Websphere and old
JBossTM (not Arjuna's) are gentle. The practical difference between
the two is that agressive will work fine with tricky use cases like
this one: http://www.jroller.com/page/maximdim?entry=is_xa_transaction_support_broken
Agressive is also much more performant with resources fully supporting
transaction interleaving.


> >> What do you mean by mixing local/global transactions?
> >
> > This is a common way of using a XA connection pool that mixes both
> > local and global transactions:
> >
> > c = ds.getConnection()
> > c.executeUpdate("UPDATE 1")
> > c.setAutoCommit(false)
> > c.executeUpdate("UPDATE 2")
> > tm.begin()
> > c.executeUpdate("UPDATE 3")
> > tm.rollback()
> > c.commit()
> >
> > UPDATE 1 is done in a local transaction while in autocommit mode, it
> > is committed.
> > UPDATE 2 is done in a local transaction manually committed, it is
> > committed.
> > UPDATE 3 is done in a global transaction which is rolled back, it is
> > rolled back.
> >
> > Does PostgreSQL supports this ? If not, applications using Hibernate
> > might not work as it runs queries in local transaction mode on its own
> > during startup.
>
> Hmm, we should be supporting that, but it might not work with the
> current released version given the bug with setAutoCommit reported by
> Allan Saddi recently. We should add a test case for that...

It might be possible to workaround in the TM a potential limitation of
the RM on this subject but as far as I can say, this works fine with
Oracle, Sybase, Firebird, Informix, Derby and FirstSQL.


> > It's also common even with applications not using Hibernate to execute
> > statements in local and then in global mode with the same connection.
>
> Really? In my experience, you don't write applications that directly
> interact with the TM. You leave that to the application server, and app
> servers just always start a XA transaction because it doesn't know
> beforehand if a transaction is going to be global or local.

That's correct for CMT but I've seen more applications requiring XA
where JTA transactions were controlled manually with BMT or that
weren't using EJBs at all. In those cases, a JTA transaction is only
started when it is known that two resources will be impacted.

Am I biaised by relying on my sole experience ?


> I believe the limitations in Oracle and Sybase are the same as in
> PostgreSQL: you can't do transaction interleaving. Or do they support
> some limited kind of transaction interleaving that we don't? If they do,
>   we could see what it would take for us to support those scenarios as well.

I believe Oracle supports transaction interleaving in its engine as
OCI has a very complete set of functions to manipulate transactions:
http://www.stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10779/oci08sca.htm
There are some limitations but it works well for most cases.

FirstSQL, Firebird and Informix fully support transaction interleaving
with no restiction.


> DB2 had problems when I tested it, search the archives for details. I
> wonder how MS SQL Server works?

No idea as I never tested any of these two.


As you were right on the TMSUSPEND discussion, please ignore my
arguments against TM workarounds as they are bogus.

Ludovic

Re: Postgres XA support

From
Kris Jurka
Date:

On Tue, 10 Oct 2006, Heikki Linnakangas wrote:

> Ludovic Orban wrote:
>
>> This is a common way of using a XA connection pool that mixes both
>> local and global transactions:
>>
>> c = ds.getConnection()
>> c.executeUpdate("UPDATE 1")
>> c.setAutoCommit(false)
>> c.executeUpdate("UPDATE 2")
>> tm.begin()
>> c.executeUpdate("UPDATE 3")
>> tm.rollback()
>> c.commit()
>>
>> UPDATE 1 is done in a local transaction while in autocommit mode, it
>> is committed.
>> UPDATE 2 is done in a local transaction manually committed, it is
>> committed.
>> UPDATE 3 is done in a global transaction which is rolled back, it is
>> rolled back.
>>
>> Does PostgreSQL supports this ? If not, applications using Hibernate
>> might not work as it runs queries in local transaction mode on its own
>> during startup.
>
> Hmm, we should be supporting that, but it might not work with the current
> released version given the bug with setAutoCommit reported by Allan Saddi
> recently. We should add a test case for that...
>

I see how Allan's patch would get UPDATE 1 to commit, but UPDATE 2 and 3
are the equivalent of an interleaved transaction and I don't see how that
could possibly work.  I'm not sure what sort of protection we need to add
to prevent people from doing this or other transaction handling actions on
the connection.  Right now the Connection object doesn't know if it is
being used by a XADatasource.

Kris Jurka

Re: Postgres XA support

From
Heikki Linnakangas
Date:
Ludovic Orban wrote:
> Kris,
>
> 2006/10/30, Kris Jurka <books@ejurka.com>:
>>
>> I see how Allan's patch would get UPDATE 1 to commit, but UPDATE 2 and 3
>> are the equivalent of an interleaved transaction and I don't see how that
>> could possibly work.  I'm not sure what sort of protection we need to add
>> to prevent people from doing this or other transaction handling
>> actions on
>> the connection.  Right now the Connection object doesn't know if it is
>> being used by a XADatasource.
>
> The problem is not if a connection was created by an XADatasource or
> not but if it is being used in a global transaction context or not.

Agreed.

> Weblogic's connection pool has a parameter called
> local-transaction-supported which when set to false will disallow
> local transactions to be executed on connections taken from that pool.

The WebLogic manual isn't very helpful, this is all I found regarding
that parameter:

"local-transaction-supported — Optional. Boolean. Set the
local-transaction-supported to true if the XA driver supports SQL with
no global transaction; otherwise, set it to false. The default value is
false."

It doesn't actually say what difference it makes or why you would want
to set it to true. I don't see how a transaction manager could generally
make use of the feature, because it doesn't know if a transaction is
distributed or not until it's committed or the second resource is enlisted.

> I guess you could enforce the same behavior in the driver by throwing
> a SQLException when some query is executed and XAResource.start() has
> not been called yet or XAResource.end() has already been called.

That seems like the easiest solution. We'll have to wrap the Connection
object returned by PGXAConnection.getConnection so we can intercept
execute-calls, though.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: Postgres XA support

From
"Ludovic Orban"
Date:
Kris,

2006/10/30, Kris Jurka <books@ejurka.com>:
>
> I see how Allan's patch would get UPDATE 1 to commit, but UPDATE 2 and 3
> are the equivalent of an interleaved transaction and I don't see how that
> could possibly work.  I'm not sure what sort of protection we need to add
> to prevent people from doing this or other transaction handling actions on
> the connection.  Right now the Connection object doesn't know if it is
> being used by a XADatasource.

The problem is not if a connection was created by an XADatasource or
not but if it is being used in a global transaction context or not.

Weblogic's connection pool has a parameter called
local-transaction-supported which when set to false will disallow
local transactions to be executed on connections taken from that pool.

I guess you could enforce the same behavior in the driver by throwing
a SQLException when some query is executed and XAResource.start() has
not been called yet or XAResource.end() has already been called.

Ludovic

Re: Postgres XA support

From
"Ludovic Orban"
Date:
Heikki,

> > Weblogic's connection pool has a parameter called
> > local-transaction-supported which when set to false will disallow
> > local transactions to be executed on connections taken from that pool.
>
> The WebLogic manual isn't very helpful, this is all I found regarding
> that parameter:
>
> "local-transaction-supported — Optional. Boolean. Set the
> local-transaction-supported to true if the XA driver supports SQL with
> no global transaction; otherwise, set it to false. The default value is
> false."
>
> It doesn't actually say what difference it makes or why you would want
> to set it to true. I don't see how a transaction manager could generally
> make use of the feature, because it doesn't know if a transaction is
> distributed or not until it's committed or the second resource is enlisted.

It's not the transaction manager but the connection pool (this is a
parameter of the connection pool, not of the TM !) that is going to
use this feature. If it detects you're using a connection outside a
tm.begin() / tm.commit() block it will throw a SQLException.

To achieve this you need tight integration between the connection pool
and the TM but that's definitely possible. I think I should implement
that as well.


> > I guess you could enforce the same behavior in the driver by throwing
> > a SQLException when some query is executed and XAResource.start() has
> > not been called yet or XAResource.end() has already been called.
>
> That seems like the easiest solution. We'll have to wrap the Connection
> object returned by PGXAConnection.getConnection so we can intercept
> execute-calls, though.

That sounds good enough.

Cheers,
Ludovic