Question

FSM Business Rule - XML


Badge +4

We have the below XML being triggered from a business rule, after commit insert or update on the TASK table.  This XML creates a new address (using a custom view) and updates the address_id of the task. 

We sometimes see that,  if there are 2 TASK’s created almost at the same time (with just 1 second delay or less than 1 second delay)  then both the task’s  are updated with the same address id. 

 

The below expression that is updating the address_id returns the same address_id in  both cases. 

<address_id xpath_node="//update_address_result[@result_name='update_tmfb_address']/address/address_id" />

 

However we see in the database that 2 new address_id are created but the both the task’s are updated with only 1 of them. 

 

So basically when we have 2 similar tasks created at the same time then this business rule executes 2 times and the expression “//update_address_result[@result_name='update_tmfb_address']/address/address_id" doesn’t return unique result.  The task ‘s are updated with the same address_id.  

 

If these 2 tasks are created with a delay  then both the task’s are updated correctly with their own new address_id.

 

Is it a bug in the system that when the XML’s are triggered simultaneously the xpath_node doesn’t get the correct result. it just returns whatever is there in the execution result ?

OR

Is there a way to assign the “result_name” dynamically so that we can make it unique so that this case can be handled ?

 

 

 

************************************************************************

<perform_batch>


 <sequential_dependent>


  <hierarchy_select result_name="select_address">
   <attrs>
    <attr>C_TMFB_ADDRESS.address_id</attr>
    <attr>C_TMFB_ADDRESS.address</attr>
    <attr>C_TMFB_ADDRESS.latitude</attr>
    <attr>C_TMFB_ADDRESS.longitude</attr>
   </attrs>
   <primary_table>C_TMFB_ADDRESS</primary_table>
   <from>
    <table>C_TMFB_ADDRESS</table>
   </from>
   <where>
    <data_constraint>
     <constraint>
      <left_operand>C_TMFB_ADDRESS.address_id</left_operand>
      <operator>eq</operator>
      <right_operand>@address_id</right_operand>
     </constraint>
    </data_constraint>
   </where>
  </hierarchy_select>

 

  <hierarchy_select result_name="select_existing_address">
   <attrs>
    <attr>ADDRESS.ACTIVE</attr>
    <attr>ADDRESS.CITY</attr>
    <attr>ADDRESS.COUNTRY</attr>
    <attr>ADDRESS.CREATED_BY</attr>
    <attr>ADDRESS.CREATED_DTTM</attr>
    <attr>ADDRESS.LACK_OF_COVERAGE</attr>
    <attr>ADDRESS.LOCALITY</attr>
    <attr>ADDRESS.MODIFIED_BY</attr>
    <attr>ADDRESS.MODIFIED_DTTM</attr>
    <attr>ADDRESS.NAME</attr>
    <attr>ADDRESS.REGION</attr>
    <attr>ADDRESS.USER_DEF1</attr>
    <attr>ADDRESS.USER_DEF2</attr>
    <attr>ADDRESS.USER_DEF3</attr>
    <attr>ADDRESS.USER_DEF5</attr>
    <attr>ADDRESS.ZIPPOST</attr>
   </attrs>
   <primary_table>ADDRESS</primary_table>
   <from>
    <table>ADDRESS</table>
   </from>
   <where>
    <data_constraint>
     <constraint>
      <left_operand>ADDRESS.address_id</left_operand>
      <operator>eq</operator>
      <right_operand>@address_id</right_operand>
     </constraint>
    </data_constraint>
   </where>
  </hierarchy_select>

 

  <update_address regex_validated="true" result_name="update_tmfb_address">
   <address>
    <insert is_initialized="false" />
    <address xpath_node="//c_tmfb_address_hierarchy_select_result[@result_name='select_address']/c_tmfb_address/address" />
    <geocode_lat xpath_node="//c_tmfb_address_hierarchy_select_result[@result_name='select_address']/c_tmfb_address/latitude" />
    <geocode_long xpath_node="//c_tmfb_address_hierarchy_select_result[@result_name='select_address']/c_tmfb_address/longitude" />
    <active xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/active" />
    <city xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/city" />
    <country xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/country" />
    <created_by>SYSTEMUSER</created_by>
    <created_dttm xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/created_dttm" />
    <lack_of_coverage xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/lack_of_coverage" />
    <locality xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/locality" />
    <modified_by>SYSTEMUSER</modified_by>
    <modified_dttm xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/modified_dttm" />
    <name xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/name" />
    <region xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/region" />
    <user_def1>@request_id</user_def1>
    <user_def2>FSM</user_def2>
    <user_def3 xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/user_def3" />
    <user_def5 xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/user_def5" />
    <zippost xpath_node="//address_hierarchy_select_result[@result_name='select_existing_address']/address/zippost" />
   </address>
  </update_address>

 

<update_task>
   <task>
    <task_id>@task_id</task_id>
    <address_id xpath_node="//update_address_result[@result_name='update_tmfb_address']/address/address_id" />
    <modified_by>SYSTEMUSER</modified_by>
    <update />
   </task>
  </update_task>


 </sequential_dependent>


</perform_batch>


11 replies

Userlevel 4
Badge +5

Have you tried setting your custom business process to synchronous (check the box)?

I haven’t tried it, but you might be able to produce a dynamic result_name attribute by putting @task_id in it like this: 
         result_name="update_tmfb_address@task_id"

 

With a little luck, that might produce “update_tmfb_address12345”
 in the XML response message.

Badge +4

Yes Mike, the custom process is marked as Synchronous (check box is checked).

I have tried this already it takes up the literal string and doesn’t replace with the task id. 

Userlevel 4
Badge +5

As a work around, you could try setting one of the user_def fields on the address record insert to the @task_id.  Then have a custom business process on address table after commit insert which looks to the user_def field and updates the task record for the task_id value in the address user_def field.  I know this is not tidy and neat, but it might get you where you need to be - unless, of course, the original task transaction and business process are triggered by a change to task.address_id.  In that case, you’d get a circular reference and your business processes would loop… which makes me wonder.. do you already have that condition?!

It is conceivable, if you are triggering the business process based on the update of task.address_id, that you have a circular race condition.

Badge +4

Yeah I already have that condition  to handle update scenarios, and I did got this circular loop but then I fixed it by adding a user id check (<modified_by>SYSTEMUSER</modified_by>)  

After commit update , I am checking if the update is not from SYSTMUSER then do my stuff else it evaluates to false.

Badge +4

But I do not have anything for update on the address table. I am trying to think about the workaround. :)

Badge +4

But this problem , it can also happen for other results in the batch

result_name='select_address'

result_name='select_existing_address'

Userlevel 4
Badge +5

Are you sure the other queries are giving you unpredictable results?  I was thinking it is a problem only with the insert of the address and the new address_id values?

Badge +4

Yeah just those 2 ,  the other gives predictable results. 

What i meant was it can happen to any query where you want to fetch some values using xpath.

 

Userlevel 4
Badge +5

So where are you with this?  Have you been able to change the implementation as I suggested, or are you still stuck?

Badge +4

Hi,

I have moved the below update part to another business rule “after commit insert” on ADDRESS table.

<update_task>
   <task>
    <task_id>@user_def6</task_id>
    <address_id>@address_id</>
    <modified_by>SYSTEMUSER</modified_by>
    <update />
   </task>
  </update_task>

 

It works,  but I am not confident as the part inserting the new address also refers to an XPath expression and they also can get mixed up in the situation when 2 similar tasks are created at the same time. So I might end up with the wrong address’s even though the tasks will have different address_id. I hope you get what I mean.

//c_tmfb_address_hierarchy_select_result[@result_name='select_address']

//address_hierarchy_select_result[@result_name='select_existing_address']

 

Regards,

Sourabh Jain

Userlevel 4
Badge +5

I think you’ll be fine.  The address and the address ID can’t get separated because the address ID is the PK for the address record, and you’re capturing THAT exact value when the address record is created.

Reply