Responsive Ads Here

Sunday, June 3, 2018

Mule Soft: Transaction Rollback


In some cases, we may have to rollback transaction if any exception occurred. Mule provides transactional property. With the help of this transactional tag we can handle rolling back transaction if any exception occurred.
e.g.
In any bank system, suppose there are two accounts A and B. We need to transfer $100 from A to B. Transaction will be complete if and only if money deducted from A and Credited into B. In any other case transaction must me rolled back.
Suppose, DB Query deducted amount from A, but Query failed when crediting B, amount deducted from A must be returned. This type of scenario can be handled in mule.
<transactional action="ALWAYS_BEGIN"doc:name="Transactional">
<db:update config-ref="MySQL_Configuration"doc:name="Database">
            <db:parameterized-query><![CDATA[UPDATE bank_account.A SET balance = (balance - 100) WHERE id = 2;]]>
</db:parameterized-query>
      </db:update>
      <db:update config-ref="MySQL_Configuration"doc:name="Database">
            <db:parameterized-query><![CDATA[UPDATE bank_account.B SET balance = (balance + 100) k id = 1;]]></db:parameterized-query>
      </db:update>
</transactional>

Transactional will automatically rollback complete transaction if any exception occurred.
We cannot use JMS directly into transactional tag. Whereas we can achieve this throw http endpoint. Where another flow can interact with JMS if needed.
e.g.
<transactional action="ALWAYS_BEGIN"doc:name="Transactional">
      <db:update config-ref="MySQL_Configuration"doc:name="Database">
            <db:parameterized-query><![CDATA[UPDATE bank_account.account SET balance = (balance - 100) WHERE id = 2;]]></db:parameterized-query>
      </db:update>
      <http:request config-ref="HTTP_Request_Configuration"
                        path="/jms"method="POST" target="#[payload]"doc:name="HTTP_Call_JMS_FLOW" />
      <db:update config-ref="MySQL_Configuration"doc:name="Database">
            <db:parameterized-query><![CDATA[UPDATE bank_account.account SET balance = (balance + 100) k id = 1;]]></db:parameterized-query>
      </db:update>
     
      </transactional>
</flow>
<flow name="JMS_FLOW">
      <http:listener config-ref="HTTP_Listener_Configuration"
                  path="/jms"doc:name="HTTP" allowedMethods="POST"/>
      <jms:outbound-endpoint queue="jms_seperate_flow"
                  doc:name="JMS_4"connector-ref="Active_MQ" />
</flow>


If we want to customize response before sending it back to client. We need to catch the exception. But if we catch exception, transaction will not roll back automatically. We must have to specify rollback exceptional strategy, like below:
<flow>
<transactional action="ALWAYS_BEGIN"doc:name="Transactional">
<db:update config-ref="MySQL_Configuration"doc:name="Database">
            <db:parameterized-query><![CDATA[UPDATE bank_account.account SET balance = (balance - 100) WHERE id = 2;]]></db:parameterized-query>
      </db:update>
      <http:request config-ref="HTTP_Request_Configuration"
      path="/jms"method="POST" target="#[payload]"doc:name="HTTP_Call_JMS_FLOW" />
                 
      <db:update config-ref="MySQL_Configuration"doc:name="Database">
            <db:parameterized-query><![CDATA[UPDATE bank_account.account SET balance = (balance + 100) k id = 1;]]></db:parameterized-query>
      </db:update>
<rollback-exception-strategy doc:name="Rollback Exception Strategy">
            <!-- This is optional -->
            <set-payload value="Custom Message"                                           doc:name="Custom_Message"/>
            <jms:outbound-endpoint queue="rollback_queue_exception"
                  connector-ref="Active_MQ"doc:name="JMS_1" />
      </rollback-exception-strategy>
</transactional>
<catch-exception-strategy doc:name="Catch_Exception_Strategy">
<set-payload value="Custom Message that needs to be sent to client" doc:name="Custom_Message"/>
      <jms:outbound-endpoint queue="rollback_queue_catch_exception"
                        connector-ref="Active_MQ"doc:name="JMS_3" />
</catch-exception-strategy>
</flow>
<flow name="JMS_FLOW">
      <http:listener config-ref="HTTP_Listener_Configuration"
                  path="/jms" doc:name="HTTP"allowedMethods="POST" />
      <jms:outbound-endpoint queue="jms_seperate_flow"
                  doc:name="JMS_4" connector-ref="Active_MQ"/>
</flow>

No comments:

Post a Comment