2011-12-13 8 views
6

Trong API doc JMS, nó nói:Hàng đợi JMS nhận được tin nhắn?

public Message receive() throws JMSException 

Nhận được thông báo tiếp theo sản xuất cho người tiêu dùng thông báo này. Cuộc gọi này chặn vô thời hạn cho đến khi một tin nhắn được tạo ra hoặc cho đến khi người tiêu dùng tin nhắn này bị đóng.

Nếu việc nhận này được thực hiện trong một giao dịch, người tiêu dùng sẽ giữ lại tin nhắn cho đến khi giao dịch được thực hiện.

Ở đây tôi có ba câu hỏi: 1. trong mã, chúng tôi có cần vòng lặp while để nhận tin nhắn không? như:

while(true){ 
    Message msg = queue.receive(); 
    .... 
} 
  1. các thiết lập giao dịch là gì? làm thế nào để thực hiện một giao dịch? như thế này:

    boolean transacted = false; 
    session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE); 
    
  2. receiveNoWait() có hỗ trợ giao dịch? Làm thế nào để sử dụng nó ?

Cảm ơn

Trả lời

3
  1. Nếu bạn đang sử dụng nhận thì bạn sẽ cần một số loại vòng lặp để tiếp tục nhận được thông điệp sau khi người đầu tiên nhận được. Hãy nhớ rằng bạn cũng có thể thiết lập một trình tạo rối và nhận được các tin nhắn nhận được không đồng bộ thông qua một phương thức gọi lại và không phải chặn.

  2. Giao dịch thường được đặt thành AUTO_ACKNOWLEDGE theo mặc định có nghĩa là ngay sau khi thư được lấy từ hàng đợi nó đã biến mất và không thể khôi phục được. Nếu bạn muốn thiết lập giao dịch, bạn cần đặt phiên giao dịch thành giao dịch và phương thức thành SESSION_TRANSACTED. Khi bạn gọi cam kết() trên phiên, các thông báo sẽ được xác nhận trên hàng đợi.

  3. receiveNoWait() có thể có hỗ trợ giao dịch nếu bạn thiết lập chế độ xác nhận chính xác và bạn sử dụng commit() và rollback() trên phiên.

Nếu tôi là bạn, tôi sẽ tạo một MessageListener và không phải lo lắng về việc quay chuỗi để thăm dò phương thức nhận. Hãy nhớ rằng một giao dịch ngầm được bắt đầu khi phiên được tạo.

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

nếu sử dụng giao dịch, nó sẽ làm giảm hiệu suất? – user595234

+0

Giao dịch áp đặt phí trên máy chủ JMS vì nó không thể phát hành tin nhắn cho đến khi bạn cam kết. – gregwhitaker

+0

Bạn cũng có thể xem xét một số gợi ý về hiệu suất trên JMS với Java: http://www.precisejava.com/javaperf/j2ee/JMS.htm – gregwhitaker