2017-02-03 6 views
1

私はスタジオを使ってこの問題を解決する方法を理解するのに苦労しており、おそらくSOの良いユーザーに手を差し伸べると助けになるかもしれないと考えました。データベースの同期とWebサービスの選択

私はクライアントからリクエストを受け取るシンプルなWebサービスを持っています。この要求はデータベーステーブルへの挿入を実行し、このデータベースを事実上メッセージキューとして使用します。別のプロセスが定期的にこのテーブルをポーリングし、メッセージに対して追加の処理を実行し、結果を出力テーブルに書き込みます。データベースの挿入と後続の選択は、送られたメッセージの結果を確実に得るために渡すことができるcorrelationIdによってリンクされます。残念ながら、これが統合されるソフトウェアは、このパターンが正しく機能することを要求します。

ここで必要とされているワークフローの:(?やpoll /再試行/など)

のHttpRequest - - >テーブルにレコードを挿入>待ち時間はレコードが(を持つ独立したプロセスによって、別のテーブルに書き込まれるまで同じ相関ID) - >この他のテーブルのデータをhttpRequestに戻します

ここでは、これで得られるサンプルフローがあります。奇妙なことに、このフローは実際にペイロードを返しますが、常に「1」と思われます。行が存在してから結果の行が返されるまで、この流れでデータベースクエリを再試行させる方法はよく分かりません。

2つのデータベース呼び出しをどのように同期する必要がありますか?多分コンポーネントの異なる組み合わせを使って、これはミュール内で可能でしょうか?

ありがとうございました。

<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

答えて

0

ESB Muleは素晴らしいツールですが、それはあなたの人生があまりにも簡単になります。あなたが簡単なことを忘れるほど簡単なこともあります。

あなたの場合、ペイロードは最後のコンポーネントの結果である1つのオブジェクトであることを忘れています。カートを1つだけ持つレールとしての流れを考えてみましょう。最後の駅に荷物があれば、次の駅に届けられます。その後、繰り返しを処理します。もともと駅に配達されたものは問題ではありません。あなたが読み込んだことを教えてください。

最初のデータベースコンポーネントには、CXFの元のペイロードがあり、データベースに何かが格納されています。 INSERT文の結果を返します。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を返すことを確認するだろう - レコードが挿入されています。これを行い、エラーに関するアラートを生成し、元のペイロードを復元してフローを続行します。

+0

はこのいただきありがとうございます。この類推は確かに大いに助けになり、私はこれに関するいくつかの問題を乗り越えることができます。私は、私が持っている問題を説明する仕事が貧弱かもしれないと思います。私が持っている主な問題は、「成功するまで」というコンポーネント(またはおそらく別のコンポーネント)は、レコードが別のプロセスによって挿入されるまで待たなければならず、結果の挿入がペイロードになるはずです。 – Beta033

+1

この場合、レコードが挿入されているかどうかを確認する必要があります。次に、依存する挿入を行う必要があります。期待して挿入しようとすると動作しますが、主に例外を期待するのは良い考えではありません。 「おそらく」この新しい挿入物は、おそらく良いものをロックするかもしれないし、あなたはデッドロックになるでしょう。 – Alex

+0

ありがとうアレックス、主に私がやろうとしているのは、データベースに置かれたリクエストメッセージを相関させてから、リクエスタにメッセージがデータベースからポーリングされるまで待つことです。 – Beta033

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> 
+0

私が持っている問題は実際にペイロードで値を殺すことではありません。私が持っている問題は、データベースの挿入と選択を相関させることです。 – Beta033

関連する問題