Re: XA end then join fix for WebLogic

From: Heikki Linnakangas <heikki(at)enterprisedb(dot)com>
To: ludovic orban <ludovic(dot)orban(at)gmail(dot)com>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: XA end then join fix for WebLogic
Date: 2006-11-01 10:52:32
Message-ID: 45487C70.6000604@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

ludovic orban wrote:
> Heikki,
>
> You wondered why Weblogic calls XAResource.start(TMJOIN) in this post:
> http://archives.postgresql.org/pgsql-jdbc/2006-10/msg00011.php
>
> I'm going to try to explain you why that's happening in this email.
> Please note that this explanation is solely based on my personal
> observations of multiple transaction managers/app servers. I'm writing
> this from the top of my head so I may have done a few mistakes.

Thanks for the explanation.

> The 'on statement creation' one, while more complex to write is more
> flexible (end-user wise) and is generally more performant when used
> with databases fully supporting transaction interleaving. This one
> calls XAResource.start(TMNOFLAGS) when Connection.createStatement() or
> prepareStatement() or prepareCall() is called and
> XAResource.end(TMSUCCESS) when Connection.close() is called.

Can you elaborate how 'on statement creation' is generally more
performant? It seems to me that it leads to more start/end calls. At
least in a straightforward implementation of start(TMJOIN), that means
more round-trips to the database. Have you seen or done any performance
tests on this?

You might be able to get away with a slightly smaller connection pool,
but that's with the cost of more "context switches" in the DBMS as a
connection is repeatedly associated and disassociated with a transaction.

That also makes me a bit worried about possible deadlocks. For example,
imagine this simple example:

1 public void transactionalMethod() {
2 tm.begin();
3
4 Connection c = getXADataSource().getConnection();
5 c.createStatement().executeUpdate("UPDATE ...");
6 c.close();
7
8 tm.commit();
9 }

Now consider running that with a connection pool of just 1 connection:

Thread A: runs begin + getConnection + update + close, down to line 7.
The single Connection is now released back to the pool
Thread B: runs lines 1-5, but the UPDATE blocks because of a lock held
by transaction A.
Thread A: Tries to commit, but blocks there's no connections available
in the pool.

-> deadlock.

This is an extreme example, but the same scenario is possible with a
larger connection pool, just harder to trigger.

> For a good example of the increased flexibility you get with the 'on
> statement creation' policy has been discussed by Dmitri Maximovich:
> http://www.jroller.com/page/maximdim?entry=is_xa_transaction_support_broken
> Basically only implementations using 'on statement creation'
> enlistment policy can support this special case.

Passing a Connection-object in a bean invocation just isn't sane, even
if it was allowed by the spec. What if you pass a ResultSet-object,
should it work in BeanB? What about updates to an updatable ResultSet?

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

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message ludovic orban 2006-11-01 12:07:01 Re: XA end then join fix for WebLogic
Previous Message Simon Riggs 2006-11-01 10:15:59 Re: jdbc driver performance TODO