我有一个从队列中读取的MessageBean,我们将其命名为 MainQ。 如果onMessage代码的执行引发了一个基于用户的Exception,其类型我们将命名为 UserException ,我想抓住这个并将此消息放在名为 UserErrorQ 的单独Queue上。 如果异常不属于此类型,则抛出异常以由DMQ处理。
这是我的问题:
错误:
com.sun.messaging.jms.JMSException: MQRA:DCF:allocation failure:createConnection:Error in allocating a connection. Cause: javax.transaction.RollbackException
at com.sun.messaging.jms.ra.DirectConnectionFactory._allocateConnection(DirectConnectionFactory.java:548)
at com.sun.messaging.jms.ra.DirectConnectionFactory.createConnection(DirectConnectionFactory.java:265)
at com.sun.messaging.jms.ra.DirectConnectionFactory.createConnection(DirectConnectionFactory.java:244)`
MessageBean:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {
try{
.
.
}catch(Exception e){
if(isUserExceptionWrappedInException(e){
errorQueueHandler.sendToErrorQueue(message);
}
}
}
private boolean isUserExceptionWrappedInException(Throwable t) {
if (t == null)
return false;
else if (t instanceof UserException)
return true;
else
return isUserExceptionWrappedInException(t.getCause());
}
ErrorQueueHandler:
public void sendToErrorQueue(Message message) {
try {
createConnection();
send((TextMessage)message);
} finally {
closeConnection();
}
}
private void createConnection() throws Exception {
try {
connection = connectionfactory.createConnection();
connection.start();
} catch (JMSException e) {
String msg = "Error while attempting to initialize connection to jms destination " + ERROR_QUEUE;
throw new OperationalException(msg, e, OperationalExceptionType.APPLIKASJONSTJENER);
}
}
如上所述,尝试建立连接时会发生错误。有没有人解决这个问题?
答案 0 :(得分:0)
所以,我已经找到了自己问题的答案。 connectionException的原因是ErrorQueueHandler不是EJB,而是通过CDI注入。回滚状态中不允许新的实例化,因为容器会丢弃bean实例,这就是失败的原因。我的REQUIRES_NEW注释也被忽略了,因为它属于javax api,它不会影响注入CDI的bean。
以下是一些需要注意的事项:
确保EJB具有无构造函数或 public 构造函数。修饰符很重要,因为容器需要这些修饰符才能实例化EJB。
这种方法存在一些问题。
幸运的是,我也有一个解决方案: 这里的主要问题是控制您的交易。对于这种情况,我需要3个交易:
<强>代码:强>
<强> MessageBean:强>
@EJB
QueueService queueService;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {
try{
queueService.processMessageInNewTrasaction(message);
}catch(Exception e){
throw e;
}
}
<强> QueueService:强>
import javax.jms.Message;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Stateless
public class QueueService {
@EJB
ErrorQueueHandler errorQueueHandler;
public void processMessageInNewTransaction(Message message){
try {
.
.
} catch(Exception e) {
if(isUserExceptionWrappedInException(e)
errorQueueHandler.sendToErrorQueue(message);
}
}
private boolean isUserExceptionWrappedInException(Throwable t) {
if (t == null)
return false;
else if (t instanceof UserException)
return true;
else
return isUserExceptionWrappedInException(t.getCause());
}
}
<强> ErrorQueueHandler:强>
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Stateless
public class ErrorQueueHandler{
public void sendToErrorQueue(Message message){
.
.
}
}
有用的资源:http://weblogic-wonders.com/weblogic/2011/01/10/working-with-jms-and-the-standard-issues-in-jms/