가 나는 JMS를 사용하여 MQ에 메시지를 전송하는 기능을 사용하여 웹 스피어 애플리케이션 서버에 배치 귀를 가지고 있고, 다른 큐 : 메시지를 보낸JMS 메시지를 MQ로 보내 완전히 커밋하는 방법은 무엇입니까?
ConnectionFactory cf = null;
InitialContext context = null;
String[] arrDatos_SR = null;
Connection conn = null;
Session session = null;
Queue queue = null;
Queue queue2 = null;
Destination dest = null;
Destination dest2 = null;
MessageConsumer consumer = null;
MessageProducer producer = null;
TextMessage message = null;
String comando = "";
int tamanio = 0;
String tamanio2 = "";
String cadena = "";
try {
context = new InitialContext();
cf = (ConnectionFactory) context.lookup(arrDatos[1].trim());
conn = cf.createConnection();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) context.lookup(arrDatos[2].trim());
queue2 = (Queue) context.lookup(arrDatos[3].trim());
dest = (Destination) queue;
dest2 = (Destination) queue2;
producer = session.createProducer(dest);
// Create a text message using the queue session.
TextMessage textMessage = session.createTextMessage();
textMessage.setText(arrDatos[4]);
textMessage.setJMSReplyTo(dest2);
textMessage.setJMSMessageID(arrDatos[6]);
textMessage.setJMSCorrelationID(arrDatos[7]);
producer.send(textMessage);
} catch (NamingException e) {
// TODO Auto-generated catch block
logger.error("MQSendReceive() - Exception e2 = "
+ e, e);
} catch (JMSException e) {
// TODO Auto-generated catch block
logger.error("MQSendReceive() - Exception e2 = "
+ e, e);
}
arrDatos[5] = arrDatos[5].trim();
try{
conn.start();
consumer = session.createConsumer(dest2);
Message receivedMessage = consumer.receive(Long.parseLong(arrDatos[5]) * 1000);
if(receivedMessage != null)
{
message = (TextMessage)receivedMessage;
comando = message.getText();
comando = comando.trim();
tamanio = comando.length();
tamanio2 = StringUtils.leftPad(Integer.toString(tamanio), 9, '0');
comando = StringUtils.rightPad(comando, Constantes.TAMANIO_RESPUESTA_DES_C1, ' ');
cadena = arrDatos[0] + comando + tamanio2;
}
else
{
comando = new String();
comando = "";
tamanio = comando.length();
tamanio2 = StringUtils.leftPad(Integer.toString(tamanio), 9, '0');
cadena = arrDatos[0] + comando + tamanio2;
}
arrDatos_SR = new String[2];
arrDatos_SR[0] = cadena;
arrDatos_SR[1] = arrDatos[0];
}
catch(Exception e)
{
logger.error("MQSendReceive() - Excepcion:" + e);
}
finally
{
try {
consumer.close();
session.close();
conn.close();
context.close();
} catch (JMSException e) {
// TODO Auto-generated catch block
logger.error("MQSendReceive() - Error desconectando de MQ - Excepcion:" + e);
} catch (NamingException e) {
// TODO Auto-generated catch block
logger.error("MQSendReceive() - Error desconectando de MQ - Excepcion:" + e);
}
}
return arrDatos_SR;
에서 inmediately 메시지를 수신 aa MQ Queue # 1로 전송 된 다음 다른 MQ Queue # 2 로의 전송 큐인 다른 MQ Queue # 2로 전송됩니다. 필자는 Websphere MQ Administration GUI를 사용하여 메시지를이 대기열에 넣었으며 원활하게 전송합니다. 그러나 어떤 이유로 든 내 코드를 사용하면 전송이 즉시 이루어지지 않습니다. 대신 수신이 끝난 후 (수신 제한 시간이 만료되거나 실제로 메시지를받을 때) 수행됩니다.
누군가 이런 일이 일어나는 이유를 말해 줄 수 있습니까?
UPDATE : (3 월 31 일, 2014) 나는 @LocalBean, @Singleton 및 @TransactionManagement (TransactionManagementType.CONTAINER) 주석과 EJB 컨테이너를 사용하고 있음을 언급하는 것을 잊었다. SO (http://goo.gl/JBSW7r)에서이 게시물을 읽음으로써 전체 연결을 만드는 3 개의 클래스와 공용 메서드를 사용하는 객체로 모든 객체를 사용하는 하나의 기본 클래스가 있음을 알게되었습니다. 나는이 클래스들을 동일한 주석으로 EJB로 변환하기로 결정했다. 또한 각 메소드의 @TransactionAttribute 유형을 필수, 지원 및 필수 요소로 변경하려고 시도했지만, 일부는 작동하는지 테스트했습니다. 또한 세션 줄을 다음과 같이 변경했습니다.
session = conn.createSession(true, Session.SESSION_TRANSACTED);
결과가 동일하게 나타납니다. 메시지는 MessageConsumer의 시간 초과 간격 동안 메시지가 수신되는 동안 전송 큐에 여전히 고정되어 있습니다.
누군가 내게 이런 생각을 줄 수 있습니까?
예, 저는 이것을 언급하는 것을 거의 잊었습니다. 죄송합니다. 그것은 EJB 컨테이너입니다. LocalBean 설정을 가진 Singleton Session Bean입니다. 거래 유형을 지정하지 않았습니다. Transacted에 대한 true 옵션을 사용하여 세션을 테스트했을 때, 배포시 IllegalStateException : 글로벌 트랜잭션에서 허용되지 않는 메소드가 발생했기 때문에 작동하지 않았습니다. 나는 이것이 서버가 EJB 컨테이너를 통해 커밋을 관리하고 있기 때문이라고 생각한다. 옵션을 false로 남겨두면 괜찮습니까? – Xanathos
나는 몇몇 포스트를 주변에 읽고 있었다. 먼저, EJB는 DataQueue와 MQ 큐를 연결하기 위해 또 다른 3 개의 클래스를 사용합니다. 이것들은 Session Beans가 아니기 때문에, 이것이 내가 읽었던 것에 대한 문제 (http://goo.gl/JBSW7r)가 될지도 모른다고 생각했습니다. 그래서 다른 세 개의 클래스를 Singleton Session Beans (첫 번째 세션 Beans)로 바꾸 었습니다. 나는 또한 메인 EJB에 TransactionManagement.CONTAINER와 TransactionManagementType을 추가했다. (메인에는 REQUIRED이고, 실제 연결을 만드는 클래스에는 지원되지 않는다.) 여전히 작동하지 않습니다. 내가 뭔가 잘못하고 있는거야? – Xanathos