【问题标题】:Spring 3.1 - DefaultMessageListenerContainer - How to identify errors in ErrorHandlerSpring 3.1 - DefaultMessageListenerContainer - 如何识别 ErrorHandler 中的错误
【发布时间】:2013-03-24 19:00:46
【问题描述】:

Info :: 我有一个带有 XA 事务的 DefaultMessageListener 实现。我使用了 MessageListener 实现。

场景:: 我的 XA 事务位于 DB 和 JMS Q Publish 之间。如果其中任何一个出现“数据错误”,我需要将源消息“移动”到另一个 Q 并继续处理其余消息。

问题:: 现在,如果我的 DB 事务因 DataIntegrity 错误(主键违规)而失败,那么 XA 事务将在 Container 处回滚(而不是在 MessageListener 实现中)。因此,原始消息回滚到 Q,消息侦听器无限期地被此消息卡住 - 接收和失败处理。

如何检查某些异常 - 并在容器中以不同方式处理它们,以便我可以继续处理其余消息。

银子

【问题讨论】:

    标签: spring transactions spring-jms xa


    【解决方案1】:

    嗯,这就是 XA 事务的重点——要么全部提交,要么不提交。

    如果您希望数据库事务与 Jms 事务无关,则需要

    @Transactional(propagation=Propagation.REQUIRES_NEW) 
    

    在侦听器上游的某些方法上。在侦听器中捕获并处理异常,JMS 事务将提交。

    在这种情况下(除非涉及其他资源),您确实不需要 XA - 但您确实需要处理重复消息的(小)可能性 - 如果 DB 事务提交而 JMS 事务没有提交,出于某种原因。

    见http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html

    【讨论】:

    • 谢谢加里。但我的问题有点不同。我对 XA 事务的“原子性”感到满意,即(JMS 和 DB)操作都应该发生或不发生。问题实际上是 - 如何区分不同的例外并采取相应的行动 - 例如我需要为 DataIntegrity 异常执行不同的操作 - 为 DB Resource not available aka 瞬态异常执行不同的操作。由于错误仅在 (DefaultMessageListener)Container 中引发/捕获 - 我似乎无法控制异常以采取不同的操作。我如何做到这一点?
    • 好吧,您可以在@Transactional 上设置'norollbackFor' 属性并抛出该异常,但您必须了解,在密钥冲突之前成功的任何数据库更新都将被提交。更安全的解决方案可能是为消息存储一个“坏消息”标记(在新事务中);然后,在交付时,检查 JMSRedelivered 标志并查看此消息是否在 DB 中被标记为错误,然后再尝试再次处理它。
    猜你喜欢
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多