gpt4 book ai didi

java - JMS TransactionRolledbackLocalException 导致 GlassFish 崩溃

转载 作者:行者123 更新时间:2023-12-01 11:45:46 27 4
gpt4 key购买 nike

我的基本问题:
MessageDriven bean 在某处抛出 Exception,这会导致 JMS 队列 回滚,直到它爆炸服务器崩溃了。我什至无法寻找异常来解决问题,因为服务器日志在短短几分钟内就增长到了几百 MB。

我在寻找什么:
一种首先清除JMS队列然后一劳永逸停止回滚的方法。

这就是我所做的:

   the object         stateless bean to         Message-Driven Bean     here it throws I want to send     send the ObjectMessage     to receive the message   the Exception  +-----------+      +-----------------+        +-----------------+     +----------+  |  MyObject |----->| MessageProducer |------->| MessageReceiver |---->| do stuff |  +-----------+      +-----------------+        +-----------------+     +----------+  

The object I send is a simple serializable POJO.

The MessageProducer looks like this:

@Stateless
public class MessageProducer{

@Resource(mappedName = "jms/JMSConnectionFactory")
private ConnectionFactory connectionFactory;

@Resource(mappedName = "jms/MessageReceiver")
Queue messageReceiver;

public void sendMessage(PostContainer postContainer){
MessageProducer messageProducer;
// try with resources to close everything on Exception
try(Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)){
messageProducer = session.createProducer(messageReceiver);

ObjectMessage objectMessage = session.createObjectMessage();
objectMessage.setObject(myObject);
objectMessage.setJMSRedelivered(false); // this doesn't seem to have any effect
messageProducer.send(objectMessage);
messageProducer.close();
}catch(Exception ex){
System.out.err("error when sendingMessage .. ignoring"); // when "ignoring" the Exception I thought to at least save me the enormous log messages
}
}
}

消息 bean 如下所示:

@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/MessageReceiver")
})
public class MessageReceiver implements MessageListener{

public MessageReceiver(){
}

@Override
public void onMessage(Message message){
try{
if(message instanceof ObjectMessage){
ObjectMessage objectMessage = (ObjectMessage) message;
MyObject myObject = (MyObject) objectMessage.getObject();
doStuff(myObject); // the method that handles the incoming object - here the Exception gets thrown
}
}catch(Exception ex){
System.err.println("message could not be received: " + ex.getMessage()); // still trying to ignore exceptions here
}
}
}

异常的某些部分

javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
at com.sun.ejb.containers.EJBContainerTransactionManager.checkExceptionClientTx(EJBContainerTransactionManager.java:662)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
......... (and so on....)
at com.me.MessageBeans.MessageReceiver.doStuff(MessageReceiver.java:86)
at com.me.MessageBeans.MessageReceiver.onMessage(MessageReceiver.java:61)
at sun.reflect.GeneratedMethodAccessor313.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:55)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor310.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
......... (and so on....)
Caused by: javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.

// I try to persist myObject with JPA into the database (that's what's not working right now.. but it's beside the point here
......... (and so on....)

现在是我的实际问题

:)
如何 停止我的 JMS 队列重新传送消息(导致任何 异常或无法成功传送的消息)还有其他原因吗)? (例如捕获异常、发送消息时设置一些参数...)

设置 DestinationResourcesConnectionFactories 时,是否需要在 GlassFish 中设置参数/选项

我如何手动清除队列,因为现在队列已满,并且每次部署应用程序时都会出现“重新传递消息”几分钟之内我就会收到大量日志消息。

感谢大家花时间阅读:)

最佳答案

MDB 中的事务管理很棘手。

发生的情况是,您的 JPA Facade 服务方法抛出了 java.lang.RuntimeException,这会自动将当前事务标记为回滚。因此,当它到达 MDB 中的 catch 子句时已经为时已晚。 JMS 将重试失败的事务。

任何从服务方法中转义的 java.lang.RuntimeException 都将标记 MDB 的事务以进行回滚。您可以通过在服务方法中捕获它来防止这种情况发生。

您可能需要在 JPA Facade 中使用 @TransactionAttribute(REQUIRES_NEW) 注释服务方法,以防 JPA 标记 Tx(对此不确定)或服务方法中的另一个 EJB 调用失败。

您可以按照 To Purge Messages From a Physical Destination 上的说明进行操作清除您的队列。

关于java - JMS TransactionRolledbackLocalException 导致 GlassFish 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29145974/

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