Mule 在web服务后面同步数据库插入和选择

Mule 在web服务后面同步数据库插入和选择,mule,mule-studio,Mule,Mule Studio,我正在努力找出如何在mule中使用studio来解决这个问题,并认为与SO的优秀用户联系可能会有所帮助 我有一个简单的Web服务,它接受客户机的请求。此请求将执行对数据库表的插入,有效地将此数据库用作消息队列。一个单独的进程定期轮询此表,对消息执行附加处理,然后将结果写入输出表。数据库插入和后续选择将由一个correlationId链接,我可以传递该ID以确保获得所发送消息的结果。不幸的是,与之集成的软件需要这种模式才能正常工作 以下是所需的工作流程: HttpRequest->insert r

我正在努力找出如何在mule中使用studio来解决这个问题,并认为与SO的优秀用户联系可能会有所帮助

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

以下是所需的工作流程:

HttpRequest->insert record into a table->wait(或poll/retry/etc?),直到一条记录被一个单独的进程写入另一个表(具有相同的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>


骡子是一个很好的工具,但它让你的生活变得太简单了。有时很容易忘记简单的事情

在您的例子中,您忘记了负载是最后一个组件的结果。将流想象为只有一辆车的轨道。无论你在上一站装载什么,都会被送到下一站。然后这个过程重复。最初运送到车站的东西并不重要。重要的是你装什么

在您的情况下,第一个数据库组件具有来自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>


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

骡子是很棒的工具,但它让你的生活太简单了。有时很容易忘记简单的事情

在您的例子中,您忘记了负载是最后一个组件的结果。将流想象为只有一辆车的轨道。无论你在上一站装载什么,都会被送到下一站。然后这个过程重复。最初运送到车站的东西并不重要。重要的是你装什么

在您的情况下,第一个数据库组件具有来自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>


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

避免在数据库插入后终止有效负载的实际值的最佳解决方案是使用消息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>

避免在数据库插入后终止有效负载的实际值的最佳解决方案是使用消息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>


谢谢您的帮助。这个类比当然有很大的帮助,并将允许我绕过一些与此相关的问题。我想我在解释我的问题时可能做得不好。我遇到的主要问题是“同步2个数据库调用”,基本上,“直到成功”组件(或者可能是另一个组件?)必须等到记录被单独的进程插入,结果插入应该成为有效负载。在这种情况下,您应该轮询或其他一些定期过程,检查记录是否插入。然后你应该做依赖插入。尝试插入,希望它能起作用,但大多数情况下期待异常不是好主意。“maybe”上的这个新插入可能会锁定一个好消息,您将处于死锁状态。谢谢alex,我主要想做的是关联数据库中的请求消息,然后让请求者等待,直到从数据库中轮询消息。谢谢。这个类比当然有很大的帮助,并将允许我绕过一些与此相关的问题。我想我在解释我的问题时可能做得不好。主国际空间站