Jms 需要帮助以两种方式处理MDB异常

Jms 需要帮助以两种方式处理MDB异常,jms,jboss-mdb,Jms,Jboss Mdb,我试图在处理消息时处理两种不同类型的问题 第一个问题是远程数据库是否关闭。在这种情况下,消息应该停止处理,稍后再试。此消息不应发送到DLQ,并应一直尝试,直到远程数据库启动 第二个问题是消息出现问题时。在这种情况下,它应该转到DLQ 我应该如何构造以下代码 @Override public void onMessage(Message message) { try { // Do some processing messageProcessing(message);

我试图在处理消息时处理两种不同类型的问题

第一个问题是远程数据库是否关闭。在这种情况下,消息应该停止处理,稍后再试。此消息不应发送到DLQ,并应一直尝试,直到远程数据库启动

第二个问题是消息出现问题时。在这种情况下,它应该转到DLQ

我应该如何构造以下代码

@Override
public void onMessage(Message message) {
    try {

    // Do some processing
    messageProcessing(message);  // Should DLQ if message is bad

    // Save to the database
    putNamedLocation(message);  // <<--- Exception when external DB is down

    } catch (Exception e) {
        logger.error(e.getMessage());
        mdc.setRollbackOnly();
    }
}
@覆盖
消息(消息消息)上的公共无效{
试一试{
//做一些处理
messageProcessing(message);//如果消息不正确,应该使用DLQ
//保存到数据库

putNamedLocation(message);//假设您可以在MDB的代码体中确定地检测到错误消息,我会直接将错误消息写入DLQ。这样您就可以更自由地对错误进行分类,并可以选择将不同类型的错误消息发送到不同的“类似DLQ”的服务器队列,和/或对DLQ’ed消息应用生存时间,这样就不会有被处理的希望类型消息永远堆积在队列中。您可以将@Resource注释实例变量添加到引用ConnectionFactory和队列引用的MDB类中,以支持将消息发送到目标DLQ。底线是,确保您检测到错误,并自行对消息进行DLQ

对于数据库关闭,您可以通过在获取连接或写入更新时捕获异常来检测。在这种情况下,请清理资源并引发RuntimeException。这将导致消息重新传递,但您需要检查JMS配置以了解两件事:

  • 确保最大重新交付计数足够高,否则计数将勾选,消息最终将被DLQed
  • 如果您的JMS实现支持它,请为被拒绝的消息添加一个重新传递延迟,以便为DB恢复留出一些时间,否则您的消息将在传递/拒绝循环中无休止地旋转
  • 为了避免#2(如果您的JMS实现不支持Redivery延迟,如WebSphereMQ,那么这很棘手),您可以使用JBoss JMX管理接口来停止MDB(然后重新启动)在MDB上传递。但是,您不能在处理消息的同一线程中的MDB内执行此操作,因为MDB将等待消息完成处理,而MDB不能,因为它正在等待MDB停止,而MDB不能,因为…[等等]所以…你最好的办法是启动某种岗哨,对数据库进行轮询,当它发现数据库关闭时,停止MDB,当它再次找到它时,重新启动它。有关如何执行此操作的片段,请参阅此

    最后一部分应该有助于处理由于消息验证而产生的任何意外异常。(即,DB是正常的,但由于某些原因,消息完全失效,从而导致未捕获的异常,从而导致消息被重新传递)。因为关闭DB消息不应被重新传递超过几次(因为您的哨兵),您可以检查邮件的重新送达计数,如果该计数高得离谱,则您知道您有有毒邮件,您可以将其丢弃,或DLQ


    希望这会有帮助。

    这会有帮助。我希望有更好的方法,而不是直接将消息推送到DLQ,但您的回答确实给了我一些选择!