gpt4 book ai didi

java - 如何让JMS消息发送到MQ以完全提交?

转载 作者:行者123 更新时间:2023-12-01 17:14:33 27 4
gpt4 key购买 nike

我有一个部署在 Websphere Application Server 上的 EAR,它使用一个函数通过 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;

消息被发送到 MQ 队列 #1,然后传输到另一个 MQ 队列 #2,该队列是另一个 MQ 队列 #3 的传输队列。我使用 Websphere MQ 管理 GUI 进行了测试,将消息放入此队列,并且它们传输顺利。但是,当我由于某种原因使用我的代码时,不会立即发送。相反,它是在接收结束后完成的(当超时到期或实际收到消息时)

有人可以告诉我为什么会发生这种情况吗?

更新:(2014 年 3 月 31 日)我忘记提及我正在使用带有 @LocalBean、@Singleton 和 @TransactionManagement(TransactionManagementType.CONTAINER) 注释的 EJB 容器。通过阅读 SO ( http://goo.gl/JBSW7r ) 的这篇文章,我意识到我有 3 个类来建立整个连接,还有一个 main 将所有这些类用作我使用公共(public)方法的对象。我决定也使用相同的注释将这些类转换为 EJB。我还尝试将每个方法的 @TransactionAttribute 类型一次更改为 REQUIRED、NOT SUPPORTED 和 MANDATORY,只是为了测试其中一些方法是否有效。我还将 session 行更改为:

session = conn.createSession(true, Session.SESSION_TRANSACTED); 

结果似乎是相同的。在MessageConsumer的超时时间内接收消息时,消息仍然停留在传输队列中。

有人可以给我一些关于这些的想法吗?

最佳答案

根据您对问题的描述,我相信您提供的代码正在 EJB 的上下文中执行,并且容器管理的事务有效。在 Java EE 应用服务器中,JMS 操作将由事务协调。这意味着发送实际上不会完成,直到容器在 EJB 方法末尾提交事务。

尽管您在 Java EE 应用程序服务器中创建 session 时设置了 false,但这会被忽略,并且 session 将注册到任何有效的全局事务中。

此问题的解决方案是确保 JMS 发送在没有事务的情况下执行。为此,EJB 方法应该配置为 NOT_SUPPORTED 的事务类型。

关于java - 如何让JMS消息发送到MQ以完全提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22718428/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com