[jboss-user] [JBoss Messaging] - Re: Problems at Startup with MySQL 5 and XAConnection

timfox do-not-reply at jboss.com
Tue Aug 29 03:50:25 EDT 2006


"felipeal" wrote : 
  | Forgive my ignorance (on the JBoss internals - I'm not really thaaat stupid when it comes to Java EE/XA/JTA,etc... :-), but how to achieve 2PC commit then? I mean, suppose I'm using a XADatasource for both my app's DB and my JBossMQ DB, add 100 messages in the queue, try to update the DB, get an exception and set the transaction for rollback. According to the 2PC/DTP land, the JBossMQ transaction should rollback as well. Of course, what must be rolled back is the transaction of the JBossMQ resource, not necessary its underlying database. But if the resource suspended my global-tx and started a new local-tx one, once I finished posting the 100 messages, that new tx would be committed (and ready to be consumed), right? Or am I missing something (I hope so...)?
  | 

Ok, so in a nutshell this is what happens when use a JBoss Messaging (you meant JBoss Messaging not JBoss MQ, right?) XAConnection in a global tx.

Let's say you are in an ejb method and either using a UserTransaction directly or letting the ejb container demarcate transaction boundaries for that method.

You are using the JBoss JCA resource adaptor (http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossJMSRA) to send JMS messages, and you are using an JCA XA datasource (this one *does* need to do be XA since you are using the XA capabilities of your database - make sure your db does have XA capabilities! Some don't) for your direct data access, and you are using a local tx datasource for the datasource used by JBM for its internal data access.

Either way, the application server (the JCA layer) will have managed to get two XAResources: XAResource1 obtained from XASession.getXAResource() which is an XAResource for your JMS session, and XAResource2 which is an XAResource obtained from the database you're doing direct access with.

A global tx will be started for the UserTransaction and the app server will enlist the two XAResources in the global tx. (Assuming you're using UT)

You then send a message (using XAResource1) and insert a row in your db (using XAResource2)

You then commit the UT. (Or let the app server do it for you)

(I'm going to simplify the following a little, but the basics are correct - I don't want to go through the logging the transaction manager will do (if you are using JBoss TS) - since it's not relevant to the question.)

The transaction manager calls "prepare" on XAResource1. This tells the XAResource that it must log the work done in the tx, so it can be recovered in case of failure after the prepare.

Currently JBM uses the database to log at the prepare stage - so we write the message into the database with state "prepared" - this is done with a single JDBC transaction (if there were more than one messages sent in the same tx - they would all be written in the same JDBC tx). XAResource1 returns "OK"

(Eventually we will log using JBoss TS - but that is a different story).

The app server then calls prepare on XAResource2 - what happens now depends on the implementation of your database. But assuming it supports XA properly, then *somehow* it will write and sync *something* to disc that enables it to redo the operation at a later state. XAResource2 returns "OK"

Since both resources have returned OK, the app server will go to the commit phase.

First it calls "commit" on XAResource1. JBM already has the data for the message send in the database, so we just update it's status to "committed". This happens in a single JDBC transaction  - note we do not need an XA capable database to do this - it's a straightforward non XA database update.

Next, "commit" is called onn XAResource2. The database doesn't something internal to its implementation that results in the data ending up in the committed state.

So as you can see there is no need for JBM to need an XA capable database in order to provide a fully functioning XAResource.

This is by design:

a) We can't assume the user has an XA capable database
b) Eventually we can't assume they have a database at all (think file based persistent stores)
c) We don't want to rely on the (often ropy) xa implementation of another product over which we have no control to provide such a critical feature.

"felipeal" wrote : 
  | That's what I did initially, and I thought JBoss would (by default) manage to enroll the 2 local transactions (DB and JMS) in a global/XA transaction. But once I deployed the application, the MDBs started to consume the messages before the global tx committed, so I realized something was not set correctly...
  | 

It definitely should work. If it doesn't please file a bug report.

"felipeal" wrote : 
  | Thanks again for you help (and patience :-)
  | 


No problem


View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3968008#3968008

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3968008



More information about the jboss-user mailing list