2015-03-03 93 views
1

我正在使用命令事件驅動的系統,使用JMS和Apache Camel進行路由。在以下情況下:駱駝異常/錯誤處理事務處理路由,而不會導致客戶端異常

  • 我向系統發送一個請求 - 應答命令「X」。

  • 系統通過交易駱駝路線收到「X」。

  • 在處理「X」系統發出的幾個事件,「Y」 &「Z」, 但隨着成交的路線,這些不應該被刷新 ,直到交易完成它的一部分。

  • 發生運行時異常 - 這應導致事務回滾到 。

我希望能夠攔截異常並以真正的消息(而不是例外)回覆客戶端。因此我開始實現錯誤處理程序:

onException(RuntimeException.class) 
     .handled(true) 
     .markRollbackOnly() 
     .filter(header(Header.REPLY_TO.getName()).isNotNull()) 
     .to(DESTINATION_FOR_EXCEPTION_HANDLING) 
     .to(DESTINATION_FOR_REPLIES); 

其中:

  • DESTINATION_FOR_EXCEPTION_HANDLING是一個bean,是以異常,並返回一個消息對象
  • DESTINATION_FOR_REPLIES是設定了身體豆到郵件對象

我的問題是,如果我包含「markRollbackOnly()」它:

  • 防止被刷新 「Y」 & 「Z」 - GOOD
  • 導致客戶端使得requestReply在交易所例外 - BAD

,如果我不包括它,則:

  • 「Y」 & 「Z」 就臉紅 - BAD
  • 我收到了客戶端上的真正的消息對象 - 好

如何配置駱駝以防止事務中的消息刷新,並且能夠將異常轉換爲處理的錯誤消息?

回答

0

我試過克勞斯的方法,但由於某種原因無法讓它工作,我一定誤解了或者設置了錯誤的東西。

最終,我通過在內部傳播的第二個交易解決了這個,一個錯誤處理程序然後我可以「markRollbackOnlyLast」第二次交易,但對主事務「好」消息作出響應:

TransactionTemplate newTransactionTemplate = new TransactionTemplate(platformTransactionManager); 
    newTransactionTemplate.setPropagationBehavior(PROPAGATION_REQUIRES_NEW); 
    Policy requireNewTransaction = new SpringTransactionPolicy(newTransactionTemplate); 

    onException(RuntimeException.class) 
     .onWhen(header(Header.REPLY_TO.getName()).isNotNull()) 
      .log(LoggingLevel.ERROR, EXCEPTION_STACKTRACE) 
      .to(PROCESSOR_FOR_EXCEPTION_HANDLING) 
      .to(PROCESSOR_FOR_REPLY) 
      .handled(true) 
      .markRollbackOnlyLast(); 

    from(FROM) 
     .policy(requireNewTransaction)... 
0

如果發送到這兩個目標的onException正在使用與from相同的Camel組件,那麼您需要使用一個單獨的組件,因此它們是獨立的。因爲回滾會導致它們全部回滾。

假設你使用ActiveMQ的,你只需要聲明兩個組件

<bean id="activemq" ...> 

    <bean id="activemq2" ...> 

然後在onException的使用activemq2。然後可以配置使用相同的brokerUrl和所有。而對於第二個,您可能需要將其設置爲transacted = false。

+0

將是仍不會導致客戶端出現異常,因爲原始組件仍會響應交換異常? – James 2015-03-03 13:11:31