2017-02-03 18 views
1

Я изо всех сил пытаюсь понять, как решить эту проблему в муле, используя студию, и подумал, что, возможно, обратившись к хорошим пользователям SO, может помочь.Синхронизация вставки базы данных и выбор за веб-службой

У меня есть простой веб-сервис, который принимает запрос от клиента. этот запрос будет предварительно вставлять в таблицу базы данных, эффективно используя эту базу данных в качестве очереди сообщений. Отдельный процесс периодически обследует эту таблицу, выполняет дополнительную обработку в сообщении и затем записывает результаты в таблицу вывода. вставка базы данных и последующий выбор будут связаны с помощью корреляции, которую я могу передать, чтобы гарантировать, что я получаю результат для отправленного сообщения. К сожалению, программное обеспечение, которое будет интегрировано, требует правильной работы этого шаблона.

Вот рабочий процесс, который необходим:

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

Mule является отличным инструментом, но это делает вашу жизнь слишком легко. Когда-нибудь так легко, что вы забываете про простые вещи.

В вашем случае вы забыли, что полезная нагрузка - это один объект, который является результатом последнего компонента. Подумайте о потоке в виде рельсов только с одной тележкой. Все, что вы загружаете на последней станции, доставляется на следующую. И затем процесс повторяется. То, что первоначально было доставлено на станцию, не имеет значения. Делает то, что вы загружаете.

В вашем случае первый компонент базы данных имеет исходную полезную нагрузку от 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 - запись вставляется. Сделайте это, создайте предупреждения об ошибке, а затем восстановите исходную полезную нагрузку и продолжите свой поток.

+0

Благодарю вас за это. Аналогия, безусловно, очень помогла и позволит мне обойти некоторые проблемы с этим. Я думаю, что я, возможно, сделал плохую работу, объясняя проблему, которая у меня есть. Основная проблема, которую я испытываю, - это «синхронизация 2 вызовов базы данных» в основном, компонент «до успешного» (или, возможно, другой компонент?) Должен ждать, пока запись не будет вставлена ​​отдельным процессом, и результирующая вставка должна стать полезной нагрузкой. – Beta033

+1

В этом случае вы должны опросить или какой-либо другой периодический процесс, который должен проверить, что запись вставлена. Затем вы должны сделать зависимую вставку. Пытаясь вставить в надежде, что это сработает, но главным образом ожидать исключения - это не очень хорошая идея. Эта новая вставка «возможно» может, возможно, заблокировать хороший, и вы будете в мертвой блокировке. – Alex

+0

спасибо alex, в основном то, что я пытаюсь сделать, это сопоставить сообщение с запросом, размещенное в базе данных, а затем повторить запрос, пока сообщение не будет опрошено из базы данных. – 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

 Смежные вопросы

  • Нет связанных вопросов^_^