2011-12-13 27 views
6

w API doc JMS, to powiedział:Kolejka JMS otrzymuje wiadomość?

public Message receive() throws JMSException 

Odbiera następną wiadomość wyprodukowany dla tej wiadomości konsumenta. To wywołanie blokuje się na czas nieokreślony , dopóki nie zostanie wygenerowany komunikat lub dopóki ten konsument wiadomości nie zostanie zamknięty.

Jeśli otrzymanie zostanie wykonane w ramach transakcji, konsument zachowuje komunikat do momentu zatwierdzenia transakcji.

Tutaj mam trzy pytania: 1. Czy w kodzie potrzebujemy pętli while, aby otrzymać wiadomość? jak:

while(true){ 
    Message msg = queue.receive(); 
    .... 
} 
  1. co jest ustawieniem transakcja? jak dokonać transakcji? tak:

    boolean transacted = false; 
    session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE); 
    
  2. receiveNoWait() ma wsparcie transakcji? Jak tego użyć ?

Dzięki

Odpowiedz

3
  1. Jeśli masz zamiar użyć otrzymać wtedy trzeba będzie pewnego rodzaju pętli zachować odbierania wiadomości po otrzymaniu pierwszego. Pamiętaj, że możesz również skonfigurować program Messagelistener i odbierać odebrane wiadomości asynchronicznie za pomocą metody wywołania zwrotnego i nie musisz blokować.

  2. Domyślnie transakcja jest ustawiona na AUTO_ACKNOWLEDGE, co oznacza, że ​​jak tylko wiadomość zostanie pobrana z kolejki, zniknie i nie będzie mogła zostać wycofana. Jeśli chcesz skonfigurować transakcję, musisz ustawić sesję na transakcję, a metodę na SESSION_TRANSACTED. Po wywołaniu metody commit() w sesji komunikaty zostaną potwierdzone w kolejce.

  3. Funkcja receiveNoWait() może obsługiwać transakcje, jeśli prawidłowo skonfigurujesz tryb potwierdzenia i użyjesz funkcji commit() i rollback() w sesji.

Gdybym był tobą, utworzyłbym MessageListener i nie musiałbym się martwić o wirowanie wątku, aby odpytać metody odbierania. Należy pamiętać, że niejawna transakcja jest uruchamiana po utworzeniu sesji.

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

jeśli użyjesz transakcji, zmniejszy to wydajność? – user595234

+0

Transakcje nakładają obciążenie na serwerze JMS, ponieważ nie może on zwolnić wiadomości do momentu zatwierdzenia. – gregwhitaker

+0

Możesz również zapoznać się z następującymi zaleceniami dotyczącymi wydajności JMS w Java: http://www.precisejava.com/javaperf/j2ee/JMS.htm – gregwhitaker