2011-12-13 1 views
6

Nel API doc JMS, ha detto:La coda JMS riceve un messaggio?

public Message receive() throws JMSException 

riceve il messaggio successivo prodotta per questo messaggio consumatore. Questa chiamata blocca a tempo indeterminato fino a quando non viene prodotto un messaggio o fino a quando questo messaggio non viene chiuso.

Se questa ricezione viene eseguita all'interno di una transazione, il consumatore conserva il messaggio fino a quando la transazione non viene eseguita.

Qui ho tre domande: 1. nel codice, è necessario il ciclo while per ricevere il messaggio? come:

while(true){ 
    Message msg = queue.receive(); 
    .... 
} 
  1. qual è l'impostazione delle transazioni? come effettuare una transazione? in questo modo:

    boolean transacted = false; 
    session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE); 
    
  2. receiveNoWait() ha il supporto delle transazioni? come usarlo ?

Grazie

risposta

3
  1. Se avete intenzione di utilizzare ricevere allora si avrà bisogno di una sorta di ciclo per continuare a ricevere i messaggi dopo il primo ricevuto. Ricorda che puoi anche configurare un messagelistener e ottenere i messaggi ricevuti asincroni tramite un metodo di callback e non dover bloccare.

  2. La transazione è generalmente impostata su AUTO_ACKNOWLEDGE per impostazione predefinita, il che significa che non appena il messaggio viene prelevato dalla coda, non è più disponibile e non può essere ripristinato. Se si desidera impostare una transazione, è necessario impostare la sessione da eseguire e il metodo su SESSION_TRANSACTED. Quando si chiama commit() sulla sessione, i messaggi verranno riconosciuti sulla coda.

  3. receiveNoWait() può disporre del supporto per le transazioni se si imposta correttamente la modalità di riconoscimento e si utilizza commit() e rollback() sulla sessione.

Se fossi in te, vorrei creare un MessageListener e non dovermi preoccupare di girare un thread per eseguire il polling dei metodi di ricezione. Tenere presente che una transazione implicita viene avviata una volta creata la sessione.

public class JmsAdapter implements MessageListener, ExceptionListener 
{ 
    private ConnectionFactory connFactory = null; 
    private Connection conn = null; 
    private Session session = null; 

    public void receiveMessages() 
    { 
     try 
     { 
      this.session = this.conn.createSession(true, Session.SESSION_TRANSACTED); 

      this.conn.setExceptionListener(this); 

      Destination destination = this.session.createQueue("SOME_QUEUE_NAME"); 

      this.consumer = this.session.createConsumer(destination); 

      this.consumer.setMessageListener(this); 

      this.conn.start(); 
     } 
     catch (JMSException e) 
     { 
      //Handle JMS Exceptions Here 
     } 
    } 

    @Override 
    public void onMessage(Message message) 
    { 
     try 
     { 
      //Do Message Processing Here 

      //Message sucessfully processed... Go ahead and commit the transaction. 
      this.session.commit(); 
     } 
     catch(SomeApplicationException e) 
     { 
      //Message processing failed. 
      //Do whatever you need to do here for the exception. 

      //NOTE: You may need to check the redelivery count of this message first 
      //and just commit it after it fails a predefined number of times (Make sure you 
      //store it somewhere if you don't want to lose it). This way you're process isn't 
      //handling the same failed message over and over again. 
      this.session.rollback() 
     } 
    } 
} 
+0

se si utilizza la transazione, ridimensionerà le prestazioni? – user595234

+0

Le transazioni impongono un sovraccarico sul server JMS perché non può rilasciare i messaggi finché non si esegue il commit. – gregwhitaker

+0

Puoi anche dare un'occhiata a quanto segue per alcuni consigli sulle prestazioni su JMS con Java: http://www.precisejava.com/javaperf/j2ee/JMS.htm – gregwhitaker