我有我的WebSphere Application Server,使用一個功能通過使用JMS發送消息到MQ上部署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;
被髮送的消息inmediately接收到消息到MQ隊列#1,MQ隊列#1然後被轉移到另一個MQ隊列#2,這是一個傳輸隊列到另一個MQ隊列#3。我使用Websphere MQ Administration GUI進行測試,將消息放入此隊列中,並順利傳輸。但是當我出於某種原因使用我的代碼時,發送不是立即發出的。相反,它是在接收結束後完成的(當超時到期或實際收到消息時)
有人可以告訴我爲什麼會發生這種情況?
UPDATE:(2014年3月31日),我忘了提,我使用的是@LocalBean,@Singleton和@TransactionManagement(TransactionManagementType.CONTAINER)上的註釋的EJB容器。通過從SO(http://goo.gl/JBSW7r)閱讀這篇文章,我意識到我有3個類構成整個連接,並且一個主要部分將所有這些類用作我使用公共方法的對象。我決定使用相同的註釋將這些類轉換爲EJB。我還嘗試將每種方法的@TransactionAttribute類型更改爲需要,不支持和強制一次,以測試它們中的某些是否有效。我也將會話線更改爲:
session = conn.createSession(true, Session.SESSION_TRANSACTED);
結果看起來是一樣的。在MessageConsumer的超時間隔內收到消息時,消息仍然滯留在傳輸隊列中。
有人可以給我一些雖然這些?
是的,我幾乎忘記提到這一點,對不起。它是一個EJB容器。這是一個Singleton會話Bean,具有LocalBean設置。我沒有指定交易類型。當我使用真正的Transacted選項測試會話時,它不起作用,因爲部署時會導致IllegalStateException:全局事務中不允許使用該方法。我認爲這是因爲服務器正在通過EJB容器來管理提交。所以可以將選項保留爲假,對嗎? – Xanathos
我正在閱讀一些文章。首先,我的EJB使用另外3個類來建立DataQueue和MQ隊列之間的連接。因爲這些不是Session Beans,所以我認爲這可能是問題(因爲我讀的是:http://goo.gl/JBSW7r)所以我轉而使用Singleton Session Beans中的其他3個類(就像第一個類)。我還在主EJB中添加了TransactionManagement.CONTAINER和TransactionManagementType(對於main來說,REQUIRED是REQUIRED,對於實際連接的類來說是NOT SUPPORTED)。它仍然不起作用。難道我做錯了什麼? – Xanathos