1 2 3 Previous Next 35 Replies Latest reply: Sep 1, 2006 5:27 PM by Ovidiu Feodorov RSS

JBMESSAGING-410 - Use of JmsXA in non transactional environm

Clebert Suconic Master

What's the expected behavior of XA connections when not opening an user transaction?

We should send the messages when session.close was called,
or when producer.send was called?

I looked at both JCA and Messaging specifications and dind't find any word about XA when a transaction is not opened.


Clebert Suconic

  • 1. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Tim Fox Master

    Not sure I understand the question.

    Can you elaborate?

  • 2. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Tim Fox Master

    Ok, let me try and gues what the question is asking, and attempt an answer:

    If you are sending messages via an XASession, and the XASession's XAResource instance has been enlisted in a global tx, then the messages will actually be sent when the XAResource receives a "commit" from the transaction manager.

    This will occur either when you call commit() on a UserTransaction, if you are using a UserTransaction, or if you are in a managed environment and are using container managed transactions (CMT), e.g. you are in an ejb method which where a transaction was started when the method began, and is committed when the method exits.

    It can also occur if you have manually enlisted the XAResource in a JTA gloabl tx which you have created and manually called commit on.

  • 3. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Ovidiu Feodorov Master

    Clebert's question, as far as I can tell, is what happens if you send a message using a XASession in the absence of any JTA transaction, and then close the session.

  • 4. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Clebert Suconic Master

    My question is when you using JmsXA and not enlist a transaction.

    if you add this following test to XATransactionTest, the test will hang (as the message was never sent):


    public void test_JmsXA_NonTransactional() throws Exception
     {
     Transaction suspended = TransactionManagerLocator.getInstance().locate().suspend();
    
    
     ConnectionFactory cf = (ConnectionFactory)ic.lookup("java:/JCAConnectionFactory");
    
    
     Connection conn = cf.createConnection();
    
    
    
     Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
     MessageProducer prod = session.createProducer(queue);
     prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    
     TextMessage m = session.createTextMessage("message one");
     prod.send(m);
     m = session.createTextMessage("message two");
     prod.send(m);
    
     conn.close();
    
     conn = cf.createConnection();
    
     session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
     MessageConsumer cons = session.createConsumer(queue);
    
     conn.start();
    
     TextMessage rm = (TextMessage)cons.receive();
     assertEquals("message one", rm.getText());
     rm = (TextMessage)cons.receive();
     assertEquals("message two", rm.getText());
    
     conn.close();
     }
    


  • 5. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Tim Fox Master

    If there is no JTA transaction, there is nothing to enlist, so commit can never be received by the XASession, so the message will never be sent.

  • 6. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Clebert Suconic Master

    That's the whole point ot JBMESSAGING-410.

    JBossMQ would send it if you don't have a transaction.

    If this is the expected behavior we could decide this is not a bug, and that's it.

    If this is the case I'm cool about that.


    I'm just getting started, so I can't take that decision.
    Ovidiu, what you think?


    Clebert

  • 7. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Clebert Suconic Master

    Just an idea: We could throw an Exception on send if there isn't a transaction opened.

  • 8. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Ovidiu Feodorov Master

    I am looking at the JCA spec. I'll be back with an answer shortly.

  • 9. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Elias Ross Master


    Let me just point out, that spec or not, you may want to be compatible with the JBossMQ behavior.

    If you decide against compatibility, you should also provide a non-XA pool at java:/Jms , along with the existing java:/JmsXA .

  • 10. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Tim Fox Master

    Hmmm, I find it strange that JBossMQ has different behaviour since we are using the exact same JCA layer as JBoss MQ.

    Unless JBossMQ is doing something weird internally like sending messages from an XASession if they haven't been sent when it closes - which is certainly not mandated by the JMS spec.

  • 11. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Clebert Suconic Master

    I'm digging JBossMQ code for this.

  • 12. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Ovidiu Feodorov Master

    No need, Clebert.


    This is what happens:

    For both JBossMQ and Messaging, the JCA layer creates a JMSManagedConnection instance that delegates to java:/XAConnectionFactory, active JTA transaction or not.

    If the JTA transaction is active, the XAResource instance (SpyXAResource for JBossMQ, MessagingXAResource for Messaging) is enlisted with the transaction, otherwise it is, obviously, not.

    The difference in behavior becomes apparent when sending the message. JBossMQ session tries to store the message with its SpyXAConnection's resource manager. The SpyXAResourceManager instance doesn't see any xid (xid is null) so immediately sends the message to the server. (SpyXAResourceManager line 115)

    Messaging holds the message in its ResourceManager, associating it with a transaction that will never commit.

    So the difference is in the JMS implementation, not in the JCA layer, which is identical in both cases, as Tim thoughtfully noticed.

    Now the question is what behavior is correct. Well, the common sense says that there is no active JTA transaction at the time of Session creation, the Session is NOT transacted, so JBossMQ behavior is correct. I would treat the current Messaging behavior as a bug.

    If you have spec paragraphs to throw at me, go ahead. I am still poring over specs.

  • 13. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Clebert Suconic Master

    The only thing that brought my attention was 14.4.7 from JCA.

    I'm not sure what is a Non-managed environment:


    Transaction Inflow in a Non-managed Environment

    Though the transaction inflow contract is primarily intended for a managed environment, it may be used in a non-managed environment provided the
    application that bootstraps a resource adapter instance is capable of functioning as a resource manager.

    In a non-managed environment, support for the transaction inflow contract is not required. That is, the getXATerminator method of the bootstrapContext instance may return a null instance.


  • 14. Re: JBMESSAGING-410 - Use of JmsXA in non transactional envi
    Tim Fox Master

    Interesting.

    I'm not sure the spec is going to help here.

    I think many users have become lazy and use JmsXA for everything (i.e. stuff which doesn't require JmsXA) which results in them not really knowing the difference between it and the standard JMS connection factories.

    If we want them to be able to let them continue using JmsXA for non transactional stuff then we will need to change the messaging behaviour to be the same as JBossMQ.

    So the answer, is yes, we probably need to change it or risk pissing off lots of users and breaking their apps :)



1 2 3 Previous Next