同步数据库插入并在Web服务后面选择

时间:2017-02-03 18:49:15

标签: mule mule-studio

我正在努力弄清楚如何使用工作室解决这个问题,并认为可能会对SO的优秀用户伸出援手可能会有所帮助。

我有一个简单的Web服务,它接受来自客户端的请求。此请求将执行插入到数据库表中,有效地将此数据库用作消息队列。单独的进程会定期轮询此表,对消息执行其他处理,然后将结果写入输出表。数据库插入和后续选择将通过我可以传递的correlationId链接,以确保我获得已发送消息的结果。不幸的是,这将集成的软件需要这种模式才能正常工作。

以下是所需的工作流程:

HttpRequest - >将记录插入表格 - >等待(或轮询/重试/等?),直到通过单独的进程将记录写入另一个表(具有相同的correlationId) - >将此其他表格中的数据返回给httpRequest

这是一个尽可能接近我的样本流程。奇怪的是,这个流实际上确实返回了一个有效载荷,但它似乎总是“1”。我不太清楚如何使这个流重试数据库查询,直到存在一行,然后返回结果行。

我应该如何同步2个数据库调用?这可能是在mule中使用不同的组件组合吗?

感谢。

<flow name="mainFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="hello" doc:name="HTTP"/>
    <cxf:jaxws-service doc:name="CXF" configuration-ref="CXF_Configuration" serviceClass="kansas.MuleTestServiceImpl"/>
    <db:insert config-ref="Oracle_Configuration" doc:name="Database">
        <db:parameterized-query><![CDATA[insert into tblRequest (id, correlationId) values(#[payload], #[message.correlationId])]]></db:parameterized-query>
    </db:insert>
    <until-successful objectStore-ref="MyObjectStore" maxRetries="5" millisBetweenRetries="2000" doc:name="Until Successful" > <!-- failureExpression="???" -->
        <db:select config-ref="Oracle_Configuration" doc:name="Database">
            <db:parameterized-query><![CDATA[select correlationId,msgResponse from tblResponse where correlationId = #[message.correlationId]]]></db:parameterized-query>
        </db:select>
    </until-successful>
    <logger level="INFO" doc:name="Logger" message="#[payload]"/> <!-- why is payload always = 1? -->
</flow>

enter image description here

2 个答案:

答案 0 :(得分:0)

骡子是很棒的工具,但却让你的生活变得轻松。有时候你很容易忘记简单的事情。

在您的情况下,您忘记了有效负载是一个对象,它是最后一个组件的结果。只需一辆车即可将流量视为导轨。无论你在最后一站加载什么,都会送到下一站。然后处理重复。原来送到车站的东西并不重要。对你加载的东西很重要。

在您的情况下,第一个数据库组件具有来自CXF的原始有效负载,并在数据库中存储内容。它返回INSERT语句的结果,该语句为1 - 插入一行。因此,我们的有效载荷不断提供新货物 - 1。

但是你需要来自CXF的原始有效载荷。在哪儿?它消失了 - 我们只有一个流,一对小径,一个小车。

在这种情况下该怎么办?保留所需信息不在购物车中,而在其他地方。例如,在流量变量中。将原始有效负载存储在某个变量中,然后在需要时将其恢复。喜欢这个

<flow name="mainFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="hello" doc:name="HTTP"/>
    <cxf:jaxws-service doc:name="CXF" configuration-ref="CXF_Configuration" serviceClass="kansas.MuleTestServiceImpl"/>
        <set-variable variableName="storedPaylod" value="#[payload]" doc:name="Store original payload"/>
    <db:insert config-ref="Oracle_Configuration" doc:name="Database">
        <db:parameterized-query><![CDATA[insert into tblRequest (id, correlationId) values(#[payload], #[message.correlationId])]]></db:parameterized-query>
    </db:insert>
        <set-payload value="#[flowVars.storedPaylod]" doc:name="Restore Payload"/>
    <until-successful objectStore-ref="MyObjectStore" maxRetries="5" millisBetweenRetries="2000" doc:name="Until Successful" > <!-- failureExpression="???" -->
        <db:select config-ref="Oracle_Configuration" doc:name="Database">
            <db:parameterized-query><![CDATA[select correlationId,msgResponse from tblResponse where correlationId = #[message.correlationId]]]></db:parameterized-query>
        </db:select>
    </until-successful>
    <logger level="INFO" doc:name="Logger" message="#[payload]"/> <!-- why is payload always = 1? -->
</flow>

enter image description here

好主意是检查第一个数据库组件是否真正返回1 - 插入记录。这样做,产生错误警报,然后恢复原始有效负载并继续您的流程。

答案 1 :(得分:0)

在数据库插入后避免杀死有效负载实际值的最佳解决方案是使用Message Enricher处理器。

尝试以下代码:

<flow name="mainFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="hello" doc:name="HTTP"/>
    <cxf:jaxws-service configuration-ref="CXF_Configuration" serviceClass="kansas.MuleTestServiceImpl" doc:name="CXF"/>
    <enricher source="#[payload]" target="#[flowVars.insertResponse]" doc:name="Message Enricher">
        <db:insert config-ref="Oracle_Configuration" doc:name="Database">
            <db:parameterized-query><![CDATA[insert into tblRequest (id, correlationId) values(#[payload], #[message.correlationId])]]></db:parameterized-query>
        </db:insert>
    </enricher>
    <flow-ref name="dbSelectSubFlow" doc:name="dbSelectSubFlow"/>

    <logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="dbSelectSubFlow">
    <until-successful objectStore-ref="MyObjectStore" maxRetries="5" millisBetweenRetries="2000" doc:name="Until Successful">
        <db:select config-ref="Oracle_Configuration" doc:name="Database">
            <db:parameterized-query><![CDATA[select correlationId,msgResponse from tblResponse where correlationId = #[message.correlationId]]]></db:parameterized-query>
        </db:select>
    </until-successful>
</sub-flow>