3 Replies Latest reply on Jan 23, 2007 1:36 PM by german balbastro

    MDB and connection to a remote queue with transaction

    Markus Lutum Novice

      Like
      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=91589
      I have the same or equal problem.

      I have 2 JBoss Servers(A and B). Both 4.0.5 with Messaging 1.0.1 GA

      On A I have an MDB listen on a local queue
      inside the onmessage it should get the message and send a Result to a Queue on Server B.

      Inside my MDB on A I create a connection using B´s JNDI and look for XAConnectionFactory.
      I open the session like this:

      session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);


      But after the onMessage returns the Message is still not in the DB on B.

      If I do it like
      session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

      it works.

      It works also, if I use TRUE and commit the session explicitly with session.comit(); But if then an exception on A occurs I have the Message still in A and already in B.

      Question:
      How can I span my JTA Transaction of Server A to include the send to B?


      Now some config stuff follows:
      My MDB Config:
      <message-driven>
       <ejb-name>SyncRequestSenderMDB</ejb-name>
       <ejb-class>com.XXX.send.SyncRequestSenderMDB</ejb-class>
       <transaction-type>Container</transaction-type>
       <message-driven-destination>
       <destination-type>javax.jms.Queue</destination-type>
       </message-driven-destination>
       </message-driven>
       </enterprise-beans>
       <assembly-descriptor>
       <container-transaction>
       <method>
       <ejb-name>SyncRequestSenderMDB</ejb-name>
       <method-name>*</method-name>
       </method>
       <trans-attribute>Required</trans-attribute>
       </container-transaction>
       </assembly-descriptor>


      My remote send call:
      Connection conn = null;
       MessageProducer sender = null;
       try {
      
       conn = getConnection();
       boolean transacted = true;
       session = conn
       .createSession(transacted, Session.AUTO_ACKNOWLEDGE);
      
       sender = session.createProducer(sendQueue);
      
       TextMessage tm = session.createTextMessage(syncMessage.getMessageAsString());
      
       sender.send(tm);
       Logger.debug(this, "Message sent to IM Server");
       // with this it will be send
       // session.commit();
      
       } catch (JMSException e) {
       throw new RuntimeException(
       "Problems sending Sync Message to IM Server Queue.", e);
       } finally {
       if (sender != null)
       try {
       sender.close();
       } catch (Exception ignore) {
       }
       if (session != null)
       try {
       session.close();
       } catch (Exception ignore) {
       }
       if (conn != null)
       try {
       conn.close();
       } catch (Exception ignore) {
       }
       }


        • 1. Re: MDB and connection to a remote queue with transaction
          Elias Ross Master

          BTW, if you close the connection it closes the session and sender as well.

          Anyway, what does getConnection() do? Are you using the pooled connections at java:/JmsXA ?

          • 2. Re: MDB and connection to a remote queue with transaction
            Markus Lutum Novice

             

            "genman" wrote:
            BTW, if you close the connection it closes the session and sender as well.

            I know :-)

            "genman" wrote:

            Anyway, what does getConnection() do? Are you using the pooled connections at java:/JmsXA ?

            It gets the connection and start it from the connectionfactory (of the remote server) and because it is remote it looks for XAConnectionfactory.

            The code:

            private Connection getConnection() throws JMSException {
            
             Connection connection = null;
             try {
             connection = cf.createConnection();
             connection.start();
            
             } catch (JMSException e) {
             if (connection != null)
             try {
             connection.close();
             } catch (Exception ignore) {
             }
             throw e;
             }
             return connection;
             }

            And during ejb create the remote jndi lookup for the connectionfactory is done:

            public void ejbCreate() {
             try {
             //remote jndi properties like port and url
             Properties prop = IMConstants.getIMServerProperties();
            
             Context ic = new InitialContext(prop);
            
             cf = (ConnectionFactory) ic.lookup("XAConnectionFactory");
             sendQueue = (Queue) ic.lookup(IMConstants.QUEUE_INCOMINGSYNCREQUESTS);
             ic.close();
             } catch (Exception e) {
             throw new EJBException("Failure to get connection factory or queue: "
             + e.getMessage(),e);
             }
             }