为什么mule rollback异常会传播到调用它的流?

时间:2014-11-12 16:06:29

标签: exception-handling mule esb rollback

我有一个mule项目,其中带有回滚异常的流导致在引用它的流中抛出异常。这是正常行为吗?

以下是代码:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:file="http://www.mulesoft.org/schema/mule/file"xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.5.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core     http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">
<file:connector name="File"  autoDelete="true" streaming="false" validateConnections="true" doc:name="File"/>
<flow name="rollbacktestFlow2" doc:name="rollbacktestFlow2">
    <file:inbound-endpoint path="C:\RollbackTEst\In" responseTimeout="10000" doc:name="File" connector-ref="File"/>
    <logger message="File Rx" level="INFO" doc:name="FileRx"/>
    <flow-ref name="rollbacktestFlow1" doc:name="Flow Reference"/>
    <catch-exception-strategy doc:name="Catch Exception Strategy">
        <logger message="Rollbacktestflow 2" level="INFO" doc:name="Rollbacktestflow2"/>
    </catch-exception-strategy>
</flow>
<flow name="rollbacktestFlow1" doc:name="rollbacktestFlow1" >
    <logger message="Rollback trigger" level="INFO" doc:name="RollbackTrigger"/>
    <expression-component doc:name="Expression"><![CDATA[forceException]]></expression-component>
    <rollback-exception-strategy maxRedeliveryAttempts="4" doc:name="Rollback Exception Strategy">
        <logger message="retry" level="INFO" doc:name="retry"/>
        <expression-component doc:name="Copy_of_Expression"><![CDATA[forceException]]></expression-component>
        <on-redelivery-attempts-exceeded doc:name="Redelivery exhausted">
            <logger message="exhausted" level="INFO" doc:name="exhausted"/>
        </on-redelivery-attempts-exceeded>
    </rollback-exception-strategy>
</flow>

异常的回滚部分是否应该执行4次,然后抛出重新发送的耗尽异常?

这是日志:

    INFO  2014-11-12 15:36:40,529 [main] org.mule.module.launcher.MuleDeploymentService: 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Started app 'rollbacktest'                               +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO  2014-11-12 15:36:40,544 [main] org.mule.module.launcher.DeploymentDirectoryWatcher: 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Mule is up and kicking (every 5000ms)                    +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO  2014-11-12 15:37:18,031 [[rollbacktest].File.receiver.01] org.mule.transport.file.FileMessageReceiver: Lock obtained on file: C:\RollbackTEst\In\New Text Document.txt
INFO  2014-11-12 15:37:18,048 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: File Rx
INFO  2014-11-12 15:37:18,048 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: Rollback trigger
ERROR 2014-11-12 15:37:18,079 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.exception.RollbackMessagingExceptionStrategy: 
********************************************************************************
Message               : Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
Code                  : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
             ^
[Line: 1, Column: 1] (org.mule.mvel2.PropertyAccessException)
  org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer:692 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/mvel2/PropertyAccessException.html)
2. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException)
  org.mule.el.mvel.MVELExpressionLanguage:202 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
3. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[] (org.mule.api.MessagingException)
  org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
[Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
             ^
[Line: 1, Column: 1]
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:692)
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:337)
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

INFO  2014-11-12 15:37:18,079 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: retry
ERROR 2014-11-12 15:37:18,079 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.exception.RollbackMessagingExceptionStrategy: Failed to dispatch message to error queue after it failed to process.  This may cause message loss.Logging Message here: 

org.mule.DefaultMuleMessage
{
  id=c8cf45f1-6a81-11e4-887d-005056b6086b
  payload=[B
  correlationId=<not set>
  correlationGroup=-1
  correlationSeq=-1
  encoding=UTF-8
  exceptionPayload=org.mule.message.DefaultExceptionPayload@1975a694

Message properties:
  INVOCATION scoped properties:
    originalFilename=New Text Document.txt
  INBOUND scoped properties:
    MULE_ORIGINATING_ENDPOINT=endpoint..C.Users.mik119.Desktop.RollbackTEst.In
    directory=C:\RollbackTEst\In
    fileSize=0
    originalFilename=New Text Document.txt
    timestamp=1415806637595
  OUTBOUND scoped properties:
    MULE_ENCODING=UTF-8
  SESSION scoped properties:
}
org.mule.api.MessagingException: Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:32)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:94)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:67)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.doProcess(InterceptingChainLifecycleWrapper.java:50)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:67)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.access$001(InterceptingChainLifecycleWrapper.java:22)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper$1.process(InterceptingChainLifecycleWrapper.java:66)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
    at org.mule.processor.chain.InterceptingChainLifecycleWrapper.process(InterceptingChainLifecycleWrapper.java:61)
    at org.mule.exception.TemplateMessagingExceptionStrategy.route(TemplateMessagingExceptionStrategy.java:139)
    at org.mule.exception.RollbackMessagingExceptionStrategy.route(RollbackMessagingExceptionStrategy.java:104)
    at org.mule.exception.TemplateMessagingExceptionStrategy.handleException(TemplateMessagingExceptionStrategy.java:45)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:37)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:14)
    at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:54)
    at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:50)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:28)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:13)
    at org.mule.execution.ErrorHandlingExecutionTemplate.execute(ErrorHandlingExecutionTemplate.java:59)
    at org.mule.execution.ErrorHandlingExecutionTemplate.execute(ErrorHandlingExecutionTemplate.java:30)
    at org.mule.construct.Flow.process(Flow.java:76)
    at org.mule.config.spring.factories.FlowRefFactoryBean$2.process(FlowRefFactoryBean.java:145)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
    at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:94)
    at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:67)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:102)
    at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:51)
    at org.mule.processor.AsyncInterceptingMessageProcessor.processNextTimed(AsyncInterceptingMessageProcessor.java:118)
    at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:189)
    at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:182)
    at org.mule.execution.ExecuteCallbackInterceptor.execute(ExecuteCallbackInterceptor.java:16)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:30)
    at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:14)
    at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:54)
    at org.mule.execution.ResolvePreviousTransactionInterceptor.execute(ResolvePreviousTransactionInterceptor.java:44)
    at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:50)
    at org.mule.execution.ValidateTransactionalStateInterceptor.execute(ValidateTransactionalStateInterceptor.java:40)
    at org.mule.execution.IsolateCurrentTransactionInterceptor.execute(IsolateCurrentTransactionInterceptor.java:41)
    at org.mule.execution.ExternalTransactionInterceptor.execute(ExternalTransactionInterceptor.java:48)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:28)
    at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:13)
    at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:109)
    at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:30)
    at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker.doRun(AsyncInterceptingMessageProcessor.java:181)
    at org.mule.work.AbstractMuleEventWork.run(AbstractMuleEventWork.java:39)
    at org.mule.work.WorkerContext.run(WorkerContext.java:286)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.mule.api.expression.ExpressionRuntimeException: Execution of the expression "forceException" failed.
    at org.mule.el.mvel.MVELExpressionLanguage.evaluateInternal(MVELExpressionLanguage.java:202)
    at org.mule.el.mvel.MVELExpressionLanguage.evaluate(MVELExpressionLanguage.java:154)
    at org.mule.el.mvel.MVELExpressionLanguage.evaluate(MVELExpressionLanguage.java:133)
    at org.mule.el.ExpressionLanguageComponent.process(ExpressionLanguageComponent.java:51)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
    ... 56 more
Caused by: [Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
             ^
[Line: 1, Column: 1]
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:692)
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:337)
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
    at org.mule.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
    at org.mule.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
    at org.mule.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
    at org.mule.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
    at org.mule.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
    at org.mule.mvel2.MVEL.executeExpression(MVEL.java:943)
    at org.mule.el.mvel.MVELExpressionExecutor.execute(MVELExpressionExecutor.java:72)
    at org.mule.el.mvel.MVELExpressionLanguage.evaluateInternal(MVELExpressionLanguage.java:198)
    ... 60 more
ERROR 2014-11-12 15:37:18,095 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.exception.CatchMessagingExceptionStrategy: 
********************************************************************************
Message               : Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
Code                  : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
             ^
[Line: 1, Column: 1] (org.mule.mvel2.PropertyAccessException)
  org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer:692 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/mvel2/PropertyAccessException.html)
2. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException)
  org.mule.el.mvel.MVELExpressionLanguage:202 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
3. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[] (org.mule.api.MessagingException)
  org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
[Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
             ^
[Line: 1, Column: 1]
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:692)
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:337)
    at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

INFO  2014-11-12 15:37:18,095 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: Rollbacktestflow 2

未调用耗尽的记录器,而是调用初始流中的Rollbacktestflow2记录器。

任何人都可以解释原因吗?感谢

1 个答案:

答案 0 :(得分:4)

为什么rollback-exception-strategy不会重试?

rollback-exception-strategy的行为会有所不同,具体取决于流是否有事务,以及入站连接器的类型(事务性或可靠性)。 为了能够重新处理消息,您需要一个入站传输,因此rollback-exception-strategy可以回滚事务(使用打开事务进行事务传输)或丢弃该消息并再次尝试(可靠传输)

在您的示例中,第二个流上没有入站连接器,因此rollback-exception-strategy表现为"Use Rollback Exception Strategy for Unhandled Exceptions" on the mule doc部分描述:“当流量交换模式是请求 - 响应时,回滚异常策略更改消息的有效负载并将其返回给客户端“ 虽然文档不明确,但当流没有入站连接器时,rollback-exception-strategy不会重试。

如果要实现重试的流,可以在两个流之间使用vm transport

示例:

<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
    xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
    xmlns:https="http://www.mulesoft.org/schema/mule/https"
    xmlns:file="http://www.mulesoft.org/schema/mule/file"
    xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/https http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">


<file:connector name="File" autoDelete="true" streaming="false" validateConnections="true" doc:name="File"/>

<flow name="pickFiles" >
    <file:inbound-endpoint path="/Users/ramiro/tmp/rollback/in" responseTimeout="10000" doc:name="File" connector-ref="File"/>
    <logger message="File Rx" level="INFO" doc:name="FileRx"/>
    <vm:outbound-endpoint path="buffer" exchange-pattern="one-way" doc:name="VM"/>        

    <catch-exception-strategy doc:name="Catch Exception Strategy">
        <logger message="Rollbacktestflow 2" level="INFO" doc:name="Rollbacktestflow2"/>
    </catch-exception-strategy>
</flow>

<flow name="processQueue"  >
    <vm:inbound-endpoint path="buffer" exchange-pattern="one-way" doc:name="VM">
        <vm:transaction action="ALWAYS_BEGIN" />
    </vm:inbound-endpoint>
    <logger message="about to throw Exception..." level="INFO" doc:name="RollbackTrigger"/>

    <scripting:component doc:name="throw Exception">
        <scripting:script engine="Groovy"><![CDATA[
            throw new Exception('some very bad error')
        ]]></scripting:script>
    </scripting:component>

    <!-- we never get here -->
    <file:outbound-endpoint path="/Users/ramiro/tmp/rollback/success " doc:name="dlq" connector-ref="File"/>

    <rollback-exception-strategy maxRedeliveryAttempts="4" doc:name="Rollback Exception Strategy">
        <logger message="retry" level="INFO" doc:name="retry"/>
        <on-redelivery-attempts-exceeded >
            <logger message="exhausted" level="INFO" doc:name="exhausted"/>
            <file:outbound-endpoint path="/Users/ramiro/tmp/rollback/dlq" doc:name="dlq" connector-ref="File"/>
        </on-redelivery-attempts-exceeded>
    </rollback-exception-strategy>
</flow>



</mule>

我们在此处获取文件并通过vm transport发送。第二个流从vm中选择消息,如果有异常(总是在示例中),将中止事务并尝试再次处理消息,如果失败4次,则将其发送到DLQ。

关于until-successful

您说您使用until-successful作为解决方法。在我看来,当你有一个工作单元需要作为一个事务处理(可能是一个包含多个转换和丰富的流)时,使用rollback-exception-strategy更合适,当你只需要重试时until-successful可能失败的步骤(如调用可能因临时网络状况而失败的REST服务)