-
1. Re: XATransaction outside of JBoss VM
juhalindfors Jun 30, 2003 6:26 PM (in response to halldori)Is there a reason you're not using the EJB container for transaction demarcation? Write a message and entity bean and set the transaction attributes accordingly?
Otherwise, you can get a transaction from the JMS server by looking up the XAConnectionFactory and creating a transacted session, JBoss datasources are XA aware as long as your JDBC drivers supports XA. -
2. Re: XATransaction outside of JBoss VM
halldori Jul 1, 2003 9:22 AM (in response to halldori)The reason is that a lot of code has been written and it would be too much effort to bring it into an application server.
Anyway... would I then simply look up the user transaction and begin a global transaction? Is the Transaction manager in that case aware of operations on the XAConnection? -
3. Re: XATransaction outside of JBoss VM
halldori Jul 1, 2003 9:34 AM (in response to halldori)Or should I perhaps use the JMS resource adapter? JMSXA?
-
4. Re: XATransaction outside of JBoss VM
ioparra Jul 1, 2003 1:46 PM (in response to halldori)I had this similar situation when I was building a trading engine for my old company(accessed a ejb and JMS) in a single transaction. This is what I did.
Bare in mind, I did this about 1 year ago(and its still in production).
1)Use UserTransaction when you begin your work
2)create a seperate JMSSession(i think transacted)
3)do any work with your datasource/jms
4)acknowledge your jms messages
-- you may need to check this, you'll end up with dup messages if I'm wrong.
5)just commit your user transaction(not your jms session)
---this step should iterate through all the XAResource(ie, DB and JMS) and commit each one.
6)close your session
Hope that helps you out. I remember that this confused me, I've always questioned how the JMS Session level transaction worked with the Thread Context Based Transaction.
G/L
-Ivan -
5. Re: XATransaction outside of JBoss VM
halldori Jul 1, 2003 2:11 PM (in response to halldori)Thanks for your reply. I actually figured out a similar approach, but I can't even seem to get a XATransaction to work just for one queue. This is a message I posted in the JMS forum.
I also seem to have problem with getting XATransactions to work for a simple Java Application. I simply get a UserTransaction, start transaction, get the XAConnectionFactory, create the sessions/senders and send the message. At that point I get a JMS Exception with the message "Invalid transaction ID". What seems to be the problem is that when the addMessage method of SpyXAResourceManager is called there is no state for the transaction. So in effect the method startTx is never called in SpyXAResourceManager. That is because by default the SpyXASession does not do so:
SpySession( Connection conn, boolean trans, int acknowledge, boolean xaSession )
{
connection = conn;
transacted = trans;
acknowledgeMode = acknowledge;
if ( xaSession )
{
spyXAResource = new SpyXAResource( this );
}
running = true;
closed = false;
consumers = new HashSet();
//Have a TX ready with the resource manager.
if ( spyXAResource == null && transacted )
{
currentTransactionId = connection.spyXAResourceManager.startTx();
if (log.isTraceEnabled())
{
log.trace("Current transaction id: " + currentTransactionId);
}
}
}
Anyway has anybody got a clue. I appended the code:
public static void main(String[] args)
{
UserTransaction tx = null;
try
{
TestBookingFactory.initializeForTest();
log.info("JMSConnectionHelper.JMSConnectionHelper");
log.debug("JMSConnectionHelper.JMSConnectionHelper");
Hashtable env = new Hashtable();
String timeout = System.getProperties().getProperty("jnp.timeout");
if (timeout == null)
{
log.fatal("JMSConnectionHelper:JMSConnectionHelper: jnp.timeout property missing");
}
String sotimeout = System.getProperties().getProperty("jnp.sotimeout");
if (sotimeout == null)
{
log.fatal("JMSConnectionHelper:JMSConnectionHelper: jnp.sotimeout property missing");
}
String host = System.getProperties().getProperty("JMS.PROVIDER_URL");
if (host == null)
{
log.fatal("JMSConnectionHelper:JMSConnectionHelper: JMS.PROVIDER_URL property missing");
}
String contextFactory = System.getProperties().getProperty("JMS.INITIAL_CONTEXT_FACTORY");
if (contextFactory == null)
{
log.fatal("JMSConnectionHelper:JMSConnectionHelper: JMS.INITIAL_CONTEXT_FACTORY property missing");
}
String queueFactory = System.getProperties().getProperty("JMS.ConnectionFactoryName");
log.debug(queueFactory);
if (queueFactory == null)
{
log.fatal("JMSConnectionHelper:JMSConnectionHelper: JMS.ConnectionFactoryName property missing");
}
String queueName = System.getProperties().getProperty("JMS.CalidrisQueue");
if (queueName == null)
{
log.fatal("JMSConnectionHelper:JMSConnectionHelper: JMS.CalidrisQueue property missing");
}
env.put("jnp.timeout", timeout);
env.put("jnp.sotimeout", sotimeout);
env.put(Context.PROVIDER_URL, host);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
InitialContext iniCtx = new InitialContext(env);
tx = (UserTransaction) iniCtx.lookup("UserTransaction");
tx.begin();
Object tmp = iniCtx.lookup("XAConnectionFactory");
XAQueueConnectionFactory qcf = (XAQueueConnectionFactory) tmp;
JMSHashMapEntry defaultJMSQueue = new JMSHashMapEntry();
defaultJMSQueue.connection = qcf.createXAQueueConnection();
defaultJMSQueue.queue = (Queue) iniCtx.lookup(queueName);
defaultJMSQueue.session = defaultJMSQueue.connection.createXAQueueSession();
defaultJMSQueue.sender = defaultJMSQueue.session.getQueueSession().createSender(defaultJMSQueue.queue);
defaultJMSQueue.connection.start();
Message m = defaultJMSQueue.session.createTextMessage("Kalli Halli");
defaultJMSQueue.sender.send(m);
}
catch (Exception ne)
{
log.error("TestClass.main:", ne);
ne.printStackTrace();
}
System.out.println("success!");
try
{
tx.commit();
}
catch (RollbackException e)
{
log.error("TestClass.main:", e);
}
catch (HeuristicMixedException e)
{
log.error("TestClass.main:", e);
}
catch (HeuristicRollbackException e)
{
log.error("TestClass.main:", e);
}
catch (SecurityException e)
{
log.error("TestClass.main:", e);
}
catch (IllegalStateException e)
{
log.error("TestClass.main:", e);
}
catch (SystemException e)
{
log.error("TestClass.main:", e);
}
}