Author |
Message
|
paustin_ours |
Posted: Tue Dec 11, 2018 7:27 pm Post subject: mqrc 2024 while sending MQ messages in a loop |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
trying to send about 20K messages to a queue from a ejb. read a message from a queue and within the onMessage method calling a sendreponse following this sample
http://www.craigstjean.com/2016/02/WebSphere-8-5-MQ-Spring-and-Message-Driven-Beans/
i get a 2024 after 10K messages which i know is the maximum allowed uncommitted messsage on the queue manager.
thought it was coming from the send so i changed the send method to close every 5000 messages but i am still getting 2042.
Code: |
private void sendResponse(String responseData, int loopCnt) throws JMSException {
Connection jmsConnection = null;
Session session = null;
MessageProducer mp = null;
// String responseData = "out message";
TextMessage responseMessage = null;
try {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
System.out.println(timeStamp);
jmsConnection = connectionFactoryRef.createConnection();
session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
responseMessage = session.createTextMessage();
// ! Set correlation id from our original message id
//responseMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
responseMessage.setText(responseData);
mp = session.createProducer(null);
// use 30 minute expiry
mp.setTimeToLive(1000 * 60 * 30);
int x = 1;
while (x <= loopCnt)
{
if (x % 5000 == 0) {
try {
System.out.println("came here");
session.close();
jmsConnection.close();
jmsConnection = connectionFactoryRef.createConnection();
session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
responseMessage = session.createTextMessage();
responseMessage.setText(responseData);
mp = session.createProducer(null);
mp.setTimeToLive(1000 * 60 * 30);
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
}
mp.send(resourceDestRef, responseMessage);
x++;
}
String timeStamp1 = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
System.out.println(timeStamp1);
} finally {
try {
if (session != null) {
session.close();
}
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
try {
if (jmsConnection != null) {
jmsConnection.close();
}
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
}
}
|
One thing i did notice is that when i deploy the ejb the queue i am reading from has a input count of 1, when i put a message to the queue, it is read by the MDB. when i put message, the input count on the queue becomes two. not sure why. what can i do to resolve the 2024? |
|
Back to top |
|
 |
paustin_ours |
Posted: Wed Dec 12, 2018 1:56 am Post subject: |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
added a session.commit(); and now getting a null pointer exception. session object is not null though.
Code: |
private void sendResponse(String responseData, int loopCnt) throws JMSException {
Connection jmsConnection = null;
Session session = null;
MessageProducer mp = null;
// String responseData = "out message";
TextMessage responseMessage = null;
try {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
System.out.println(timeStamp);
jmsConnection = connectionFactoryRef.createConnection();
//session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
session = jmsConnection.createSession(true, 0);
responseMessage = session.createTextMessage();
// ! Set correlation id from our original message id
//responseMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
responseMessage.setText(responseData);
mp = session.createProducer(null);
// use 30 minute expiry
mp.setTimeToLive(1000 * 60 * 30);
int x = 1;
while (x <= loopCnt)
{
if (x % 5000 == 0) {
try {
System.out.println("came here******************");
// session.close();
//jmsConnection.close();
//jmsConnection = connectionFactoryRef.createConnection();
//session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// responseMessage = session.createTextMessage();
//responseMessage.setText(responseData);
//mp = session.createProducer(null);
//mp.setTimeToLive(1000 * 60 * 30);
if (session != null) {
System.out.println("session not null and committing");
session.commit();
}
// responseMessage = session.createTextMessage();
//responseMessage.setText(responseData);
System.out.println("came here1***************");
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
}
System.out.println("came here2 " + x);
if (responseMessage == null) {
System.out.println("resp msg null");
}
if(mp.equals(null)) {
System.out.println("mp is null test1");
}
if (mp == null ) {
System.out.println("mp is null");
}
mp.send(resourceDestRef, responseMessage);
x++;
System.out.println("came here3 " + x);
if (session.equals(null)) {
System.out.println("session null - 2");
}
}
String timeStamp1 = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
System.out.println(timeStamp1);
} finally {
try {
if (session != null) {
session.close();
}
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
try {
if (jmsConnection != null) {
jmsConnection.close();
}
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
}
}
|
|
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Dec 12, 2018 5:37 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
What is the transactional setting on the reader MDB?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
paustin_ours |
Posted: Tue Dec 18, 2018 11:25 am Post subject: |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
sorry about the late reply, i missed your response somehow.
this is the entire code that i am trying
Code: |
package com.loadtest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
/**
* Message-Driven Bean implementation class for: LoadTestMDB
*/
@MessageDriven(
activationConfig = { @ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class LoadTestMDB implements MessageListener {
// @Resource
private MessageDrivenContext mdCtx;
// @Resource(name = "mdtest/myQCF")
private ConnectionFactory connectionFactoryRef;
// @Resource(name = "mdtest/loadQout")
private Destination resourceDestRef;
/**
* Default constructor.
*/
public LoadTestMDB() {
// TODO Auto-generated constructor stub
}
/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
// TODO Auto-generated method stub
TextMessage msg = (TextMessage) message;
try {
System.out.println(msg.getText());
String[] output = msg.getText().split(":");
System.out.println("count is -" + output[1]);
int loopCnt = Integer.parseInt(output[1]);
String responseData = output[0];
sendResponse(responseData,loopCnt);
} catch (JMSException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}catch(Exception ioe){
//System.out.println("Exception while getting MQ properties()"+ ioe.getMessage());
ioe.printStackTrace();
}
}
private void sendResponse(String responseData, int loopCnt) throws JMSException {
Connection jmsConnection = null;
Session session = null;
MessageProducer mp = null;
// String responseData = "out message";
TextMessage responseMessage = null;
// ConnectionFactory connectionFactory;
// InitialContext
try {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
System.out.println(timeStamp);
jmsConnection = connectionFactoryRef.createConnection();
//session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
session = jmsConnection.createSession(true, 0);
responseMessage = session.createTextMessage();
// ! Set correlation id from our original message id
//responseMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
responseMessage.setText(responseData);
mp = session.createProducer(null);
// use 30 minute expiry
mp.setTimeToLive(1000 * 60 * 30);
int x = 1;
while (x <= loopCnt)
{
if (x % 5000 == 0) {
try {
System.out.println("came here******************");
// session.close();
//jmsConnection.close();
//jmsConnection = connectionFactoryRef.createConnection();
//session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// responseMessage = session.createTextMessage();
//responseMessage.setText(responseData);
//mp = session.createProducer(null);
//mp.setTimeToLive(1000 * 60 * 30);
if (session != null) {
System.out.println("session not null and committing");
session.commit();
}
// responseMessage = session.createTextMessage();
//responseMessage.setText(responseData);
System.out.println("came here1***************");
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
}
System.out.println("came here2 " + x);
if (responseMessage == null) {
System.out.println("resp msg null");
}
if(mp.equals(null)) {
System.out.println("mp is null test1");
}
if (mp == null ) {
System.out.println("mp is null");
}
mp.send(resourceDestRef, responseMessage);
x++;
System.out.println("came here3 " + x);
if (session.equals(null)) {
System.out.println("session null - 2");
}
}
String timeStamp1 = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
System.out.println(timeStamp1);
} finally {
try {
if (session != null) {
session.close();
}
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
try {
if (jmsConnection != null) {
jmsConnection.close();
}
} catch (JMSException e) {
Exception ex=e.getLinkedException();
System.out.println("Exception in method QueueSend.sendMessage()"+ex.getMessage());
ex.printStackTrace();
}
}
}
}
|
i dont see where a transaction property set on the reader. Are you saying the reader is the one causing the uncommited message count exception? |
|
Back to top |
|
 |
paustin_ours |
Posted: Tue Dec 18, 2018 12:17 pm Post subject: |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
tried setting
Code: |
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
@MessageDriven(
activationConfig = { @ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class LoadTestMDB implements MessageListener {
|
still getting null pointer exception at the commit |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Dec 18, 2018 8:35 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
paustin_ours wrote: |
tried setting
Code: |
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
@MessageDriven(
activationConfig = { @ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class LoadTestMDB implements MessageListener {
|
still getting null pointer exception at the commit |
If you are using a J2EE server you can't access the session.
You will need to set a requires new transaction so that each message has it's own transaction and is committed at the end of the MDB.
There may be ways to have a user handled transaction in the MDB and keep some kind of message count to do a commit every so often, but you need to look at the mdb in details and perhaps overwrite some of the default methods...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
paustin_ours |
Posted: Thu Dec 27, 2018 6:42 am Post subject: |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
cam across UserTransaction in bean managed container. probably what i need, will try to dig some more.
my understanding is that i need to start a transaction in the on message method and close it after read and create a new one to write messages out in a loop. will let you know if i am successful. thanks. |
|
Back to top |
|
 |
paustin_ours |
Posted: Thu Dec 27, 2018 6:42 am Post subject: |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
cam across UserTransaction in bean managed container. probably what i need, will try to dig some more.
my understanding is that i need to start a transaction in the on message method and close it after read and create a new one to write messages out in a loop. will let you know if i am successful. thanks. |
|
Back to top |
|
 |
paustin_ours |
Posted: Wed Jan 02, 2019 7:46 am Post subject: |
|
|
Yatiri
Joined: 19 May 2004 Posts: 667 Location: columbus,oh
|
cant seem to get this working. Can someone point me to a sample please. thanks. |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri Jan 04, 2019 9:55 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
paustin_ours wrote: |
cant seem to get this working. Can someone point me to a sample please. thanks. |
Glassfish used to have great samples. The trick is to understand that the base oracle JMS implementation and the IBM one make no difference in the transaction handling. The only difference should be the JMS provider.
You could totally have a container managed transaction but you need to define the transactionality on the onMessage method as requires new.
Then make sure you open another session (still under the same transaction) for the outbound stuff (in a loop or not). When the inbound message is fully processed the mdb returns and the transaction completes...
 _________________ MQ & Broker admin |
|
Back to top |
|
 |
|