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-07 12:31:53
Message-ID: 45507CB9.2020206@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Hi Ludovic,

I finally put aside some time to test this..

ludovic orban wrote:
> Hi again,
>
>> 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?
>
> It is more performant because it allows greater concurrency for a
> fixed amount of connections in the pool. This of course requires that
> the DB fully supports transaction interleaving or else the wrapper has
> to use a mix of both techniques and you loose that advantage. I
> measured an average 25% speed improvement with FirebirdSQL on a highly
> concurrent test (250+ XA transactions per second).

Well, if the server has the resources to do more concurrent work than
the pool size allows, just increase the pool. If it doesn't, then it
doesn't no matter what you do.

Did you try increasing the pool size instead of interleaving normal work
and commits?

>> This is an extreme example, but the same scenario is possible with a
>> larger connection pool, just harder to trigger.
>
> Thread A won't block since commit() does not require a connection, it
> just needs to use the reference it kept on the enlisted XAResource to
> be able to execute the 2PC protocol. Refer to the JTA spec chapter
> 3.4.6, Resource Sharing for details.

I guess it depends on the RM, but let's assume a typical client/server
scenario where one XAConnection has one TCP connection to the server.
The commit() will certainly have to submit the commit message to the
server somehow, and unless it uses carrier pigeons or some other
out-of-band channel, it has to use the TCP connection it has. If that
connection is busy, waiting for another query to finish, the commit will
have to wait.

In fact, because the commit() call will have to wait for the current
statement to finish, that might lead to a longer response time.
Especially if you have a mix of long and short transactions.

I just tried this with Firebird (1.5.3) and JayBird (2.1.0) that you did
your performance test with. It *does* seem to suffer from the scenario I
described. See attached test 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?
>
> I agree this isn't proper design but as you can read from the comments
> that's not the point. There are other ways to get the same kind of
> unexpected bahavior when playing with suspend/resume. Consider this
> example:
>
> tm.begin();
>
> c = getXADataSource().getConnection();
> c.createStatement().executeUpdate("UPDATE A");
>
> tx = tm.suspend();
>
> tm.begin();
> c.createStatement().executeUpdate("UPDATE B");
> tm.rollback();
>
> tm.resume(tx);
>
> c.close();
>
> tm.commit();
>
> What do you think should happen to UPDATE A and UPDATE B ? What do you
> think will happen with 'on statement creation' enlistment and with 'on
> connection acquirement' ? In my opinion, update A should be committed
> and update B rolled back. What will actually happen depends on both
> the resource and the enlistment policy implementations.

Agreed, A should be committed and B rolled back.

> With 'on statement creation' what I expect will happen: update A
> committed and update B rolled back while with 'on connection
> acquirement' both will get committed because update B is executed in a
> local transaction context since it has not been enlisted in the
> sub-transaction's context.

Umm, sub-transaction?

> While I totally agree that those examples are corner-case and not good
> examples of how things should be written, those are nevertheless traps
> that application programmers can easily fall on during the
> implementation process. I guess you can imagine how insane it is when
> you have to troubleshoot some code where you ask the TM to rollback
> and you actually see the update committed to the DB.

I can feel your pain :). Some years ago, we found out the hard way that
a FixPack to WebSphere Application Server 3.5.X (can't remember exactly)
introduced a bug that made it ignore setRollbackOnly-calls if an EJB
throwed an exception. That lead to corruption in our production
database, and the customer was not happy.

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

Attachment Content-Type Size
XATest.java text/x-java 3.8 KB

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message tomasz brymora 2006-11-07 17:19:39 PreparedStatement, getLastOID() and java.lang.ClassCastException
Previous Message Michael Paesold 2006-11-06 21:59:51 Re: JDBC Support for standard_conforming_strings