// http://jira.jboss.com/jira/browse/JBMESSAGING-721
public void testConvertFromLocalTx() throws Exception
{
Connection conn = null;
XAConnection xaConn = null;
try
{
// First send some messages to a queue
ObjectName queueMBean = new ObjectName("jboss.messaging.destination:service=Queue,name=Queue1");
Integer count = (Integer)ServerManagement.getAttribute(queueMBean, "MessageCount");
assertEquals(0, count.intValue());
conn = cf.createConnection();
Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer prod = sessSend.createProducer(queue1);
TextMessage tm1 = sessSend.createTextMessage("message1");
TextMessage tm2 = sessSend.createTextMessage("message2");
prod.send(tm1);
prod.send(tm2);
count = (Integer)ServerManagement.getAttribute(queueMBean, "MessageCount");
assertEquals(2, count.intValue());
xaConn = cf.createXAConnection();
XASession xaSession = xaConn.createXASession();
xaConn.start();
DummyListener listener = new DummyListener();
xaSession.setMessageListener(listener);
ServerSessionPool pool = new MockServerSessionPool(xaSession);
xaConn.createConnectionConsumer(queue1, null, pool, 1);
Thread.sleep(1000);
assertEquals(2, listener.messages.size());
assertEquals("message1", ((TextMessage)listener.messages.get(0)).getText());
assertEquals("message2", ((TextMessage)listener.messages.get(1)).getText());
count = (Integer)ServerManagement.getAttribute(queueMBean, "MessageCount");
assertEquals(2, count.intValue());
listener.messages.clear();
// Now we enlist the session in an xa transaction
XAResource res = xaSession.getXAResource();
tm.begin();
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
// This should cause the work done previously to be converted into work done in the xa transaction
// this is what an MDB does
// There is a difficulty in transactional delivery with an MDB.
// The message is received from the destination and then sent to the mdb container so
// it can call onMessage.
// For transactional delivery the receipt of the message should be in a transaction but by the time
// the mdb container is invoked the message has already been received it is too late - the message
// has already been received and passed on (see page 199 (chapter 5 JMS and Transactions, section
// "Application Server Integration"
// of Mark Little's book Java Transaction processing
// for a discussion of how different app serves deal with this)
// The way jboss messaging (and jboss mq) deals with this is to convert any work done
// prior to when the xasession is enlisted in the tx, into work done in the xa tx
tx.delistResource(res, XAResource.TMSUCCESS);
// Now rollback the tx - this should cause redelivery of the two messages
tm.rollback();
count = (Integer)ServerManagement.getAttribute(queueMBean, "MessageCount");
assertEquals(2, count.intValue());
Thread.sleep(1000);
assertEquals(2, listener.messages.size());
listener.messages.clear();
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
tm.commit();
Thread.sleep(1000);
assertEquals(0, listener.messages.size());
count = (Integer)ServerManagement.getAttribute(queueMBean, "MessageCount");
assertEquals(0, count.intValue());
assertNull(tm.getTransaction());
}
finally
{
if (conn != null)
{
conn.close();
}
if (xaConn != null)
{
xaConn.close();
}
/* if (suspended != null)
{
tm.resume(suspended);