2016-10-28 2 views
4

안녕하세요, MDB에 1000 개가 넘는 메시지를 보내려고하면 jms 코드에 문제가 있습니다. 다음 코드를비 트랜잭션 세션에서 JMS 트랜잭션 예외가 발생했습니다.

@Stateless(mappedName = "RequestProcessingQueue") 
public class RequestProcessingQueue { 
private static final Logger logger = Logger.getLogger(RequestProcessingQueue.class); 

@Resource(mappedName = "jmsRequestsFactory") 
private ConnectionFactory connectionFactory; 

@Resource(mappedName = "jmsRequestsDestination") 
private Queue queue; 

public void add(String participant, String password, List<Long> documents) throws JmsAppException { 

    try { 
     logger.debug("requests to process " + documents); 
     Connection connecton = connectionFactory.createConnection(); 
     connecton.start(); 
     Session session = connecton.createSession(false, Session.AUTO_ACKNOWLEDGE); 
     QueueSender sender = (QueueSender) session.createProducer(queue); 
     Message msg = msg = session.createMessage(); 
     msg.setStringProperty("participant", participant); 
     msg.setStringProperty("password", password); 

     for (Long id : documents) { 
      msg.setLongProperty("request", id); 
      sender.send(msg); 
     } 

     sender.close(); 
     session.close(); 
     connecton.close(); 
    } catch (JMSException e) { 
     throw new JmsAppException(e); 
    } catch (Throwable e) { 
     throw new JmsAppException("Fatal error occured while sending request to be processed", e); 
    } 
} 

}

MQJMSRA_DS4001: JMSServiceException on send message:sendMessage: Sending message failed. Connection ID: 2979509408914231552 com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1844)/sendMessage: Sending message failed. Connection ID: 2979509408914231552 com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1955)/transaction failed: [B4303]: The maximum number of messages [1 000] that the producer can process in a single transaction (TID=2979509408914244096) has been exceeded. Please either limit the # of messages per transaction or increase the imq.transaction.producer.maxNumMsgs property. com.sun.messaging.jmq.jmsserver.data.handlers.DataHandler.routeMessage(DataHandler.java:467)'} 
    at jms.example.RequestProcessingQueue.add(RequestProcessingQueue.java:48) 

던졌습니다 내가 세션을 만들 때 나는 그 세션을 나타내는 첫번째 PARAM로 false를 전달 왜 기분이야 이해하지 못하는 비 트랜잭션 모드입니다.

답변

2

기본 JMS API가 EJB 컨테이너 내에서뿐만 아니라 모든 환경에서 작동하도록 설계되었으므로 코드가 작동하지 않습니다. 런타임 환경 프로그래밍 제한 사항 및 동작은 EJB 사양 및 JavaDoc, 특히 javax.jms.Connection.createSession(boolean transacted, int acknowledgeMode)에 설명되어 있습니다. 귀하의 코드를 단순화 할 수

에 (적어도 자바 7 사용하고있는 가정) :

@TransactionAttribute(TransactionAttributeType.NOTSUPPORTED) 
public void add(String participant, String password, List<Long> documents) throws OgnivoException { 

    try (Connection connection = connectionFactory.createConnection(); 
     Session session = connection.createSession(); 
     // session.start() not required 
     MessageProducer sender = session.createProducer(queue)) { 
     logger.debug("requests to process " + documents); 

     for (Long id : documents) { 
      Message msg = msg = session.createMessage(); 
      msg.setStringProperty("participant", participant); 
      msg.setStringProperty("password", password); 
      msg.setLongProperty("request", id); 
      sender.send(msg); 
     } 

    } catch (JMSException e) { 
     throw new JmsAppException(e); 
    } 
    // Don't catch throwable because it hides bugs 
} 

이 별도로 지정하지 않는 한 그 EJB 방법은 자동으로 트랜잭션과 관련된 기억하십시오. 또한 javadoc에서 javax.jms.Connection.createSession() 및 관련 메소드, 특히 다른 런타임 환경에서의 동작을 설명하는 섹션을 확인하십시오.

+0

@Stave C 감사합니다! –

관련 문제