简体   繁体   English

MessageDriverBean - 重试机制

[英]MessageDriverBean - Retry mechanism

I've been reading around SO and some other google results and I got confused, some say I've to call context.setRollbackOnly();我一直在阅读 SO 和其他一些谷歌结果,但我感到困惑,有人说我必须调用context.setRollbackOnly(); other say it is not required as the MDB will do it by himself.其他人说不需要,因为MDB会自己做。

So, I've a MessageDrivenBean class that receives messages from a JMS Queue .所以,我有一个MessageDrivenBean类,它从JMS Queue接收消息。

@MessageDriven(name = "MyEventReceiverJMS", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/TheQueue"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
public class MyEventReceiverJMS implements MessageListener {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private MessageDrivenContext context;


    @Override
    public void onMessage(Message message) {

        try {
            // Some logic goes here
        } 
        catch (JMSException ex) {
            logger.error("JMSException|could not retrieve object from the message body - reason: {}", ex.getMessage());
            context.setRollbackOnly();
        } 
        catch (JSONException ex) {
            logger.error("error while creating the JSON - reason: ", ex.getMessage());
            context.setRollbackOnly();
        } 
        catch (IOException ex) {
            logger.error("could not communicate with the server - reason: {}", ex.getMessage());
            context.setRollbackOnly();
        }
    }
}

My question is, if there is an exception on the onMessage will the message (or as I call them, event) be put back on the Queue by the MDB or do I have to call context.setRollbackOnly();我的问题是,如果onMessage出现异常, message (或我称之为事件)是否会被 MDB 放回队列中,或者我是否必须调用context.setRollbackOnly(); on every catch to put the message back?在每次捕获时将消息放回?

Do I have to call context.setRollbackOnly() on every catch to put the message back ?我是否必须在每次捕获时调用 context.setRollbackOnly() 才能将消息放回?

It is up to us, If you want to roll back the message for all exceptions, yes.这取决于我们,如果您想回滚所有异常的消息,是的。 If it is a bad/poison message, there is no meaning of rolling back the transaction, it is good idea to discard by logging exception and the payload of the message.如果是坏消息/有毒消息,则没有回滚事务的意义,最好通过记录异常和消息的有效负载来丢弃。

For your first query, If there is an exception on the onMessage will the message be put back on the Queue, please find the points below:对于您的第一次查询,如果 onMessage 出现异常会将该消息放回 Queue,请查看以下几点:

The JMS Server could redeliver messages because of:由于以下原因,JMS 服务器可以重新传递消息:

A java.lang.Error or java.lang.RuntimeException has been thrown from the Receiver/MDB's onMessage method接收器/MDB 的 onMessage 方法抛出了 java.lang.Error 或 java.lang.RuntimeException

User has made a call to ejbcontext.setRollbackOnly() in his MDB's onMessage method (this applies to Container Managed Transaction only)用户在其 MDB 的 onMessage 方法中调用了 ejbcontext.setRollbackOnly()(这仅适用于容器管理事务)

MDB participating in a Transaction failed for some reason.由于某种原因,参与事务的 MDB 失败。

The below posts are really good and you can refer it for more details:以下帖子非常好,您可以参考它以获取更多详细信息:

http://weblogic-wonders.com/weblogic/2011/01/10/working-with-jms-and-the-standard-issues-in-jms/ http://weblogic-wonders.com/weblogic/2011/01/10/working-with-jms-and-the-standard-issues-in-jms/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM