Author |
Message
|
mqsiuser |
Posted: Thu Nov 13, 2014 4:34 am Post subject: Flow gets invoked two times (using MQInput and Timer node) |
|
|
 Yatiri
Joined: 15 Apr 2008 Posts: 637 Location: Germany
|
Dear experts,
I really need you help on the following:
I have a flow with an MQInput node and a Timer node.
In the debugger I can verify that the timer triggers the flow (hits breakpoint) AND then I can trigger the flow A SECOND time with putting a message into the "Trigger" queue.
I am in the debugger now, I can switch between the two (both are in a breakpoint).
This is not the desired behaviour: We want the flow to be active AT MOST ONCE.
Otherwise we will have dublicate entries in the db which lead to Exceptions (at least problems) down the road.
Pls help... (can this be controlled with the transaction settings, maybe?)
kind regards,
mqsiuser _________________ Just use REFERENCEs |
|
Back to top |
|
 |
Vitor |
Posted: Thu Nov 13, 2014 5:56 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
Does it display the same behaviour with a user trace, i.e. when the debugger is not controlling the thread behaviour for it's own purposes?
How many additional instances do you have set?
Why would you use a Timer node and an MQInput? What's the design here? _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqsiuser |
Posted: Thu Nov 13, 2014 6:16 am Post subject: |
|
|
 Yatiri
Joined: 15 Apr 2008 Posts: 637 Location: Germany
|
Thank you Vitor, you are -as always- spot on...
Vitor wrote: |
Does it display the same behaviour with a user trace, i.e. when the debugger is not controlling the thread behaviour for it's own purposes? |
I think the project's setup won't allow me to take a user trace
Vitor wrote: |
How many additional instances do you have set? |
Good questions, sorry that I didn't state initially, but it's zero (0), njada.
Vitor wrote: |
Why would you use a Timer node and an MQInput? What's the design here? |
Yes, we are questioning that also and reducing to (likely just the timer node) is an option!
Anyhow, is there something (like a checkbox) that we can set to prevent another flow invocation ?
Could this be a bug or does it work as designed? _________________ Just use REFERENCEs |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Nov 13, 2014 6:35 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Every input node always runs a separate thread.
If you don't want the possibility of a flow running twice at the same time, then you need to make sure that not only does it have only one input node, but that it has zero additional instances.
But if the only problem you are trying to solve is to prevent duplicate entries in the database, then you should solve that problem rather than trying to solve "how do I keep a flow from only running in a single thread".
It's usually easy to make sure the DB uses some part of the business data as part of a unique key, such that the DB will warn/fail if you try to insert duplicate records. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Nov 13, 2014 6:46 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
mqsiuser wrote: |
Vitor wrote: |
Does it display the same behaviour with a user trace, i.e. when the debugger is not controlling the thread behaviour for it's own purposes? |
I think the project's setup won't allow me to take a user trace |
I think you need to tell the project that you can't fix the problem without the necessary diagnostic tools. The behaviour differences between running a trace and running the debugger have been the source of much discussion here over the years.
mqsiuser wrote: |
Vitor wrote: |
How many additional instances do you have set? |
Good questions, sorry that I didn't state initially, but it's zero (0), njada. |
I had to ask.
mqsiuser wrote: |
Anyhow, is there something (like a checkbox) that we can set to prevent another flow invocation ? |
Yes, it's the additional instances setting. When this is zero, a second flow invocation will not start until the first has finished processing. Or seems to have finished processing. That's why I asked about the debugger, and why a user trace (which would not only show the state of the flow but indicate if there really are 2 different threads with 2 different PIDs) is an essential next step in the diagnostic process.
mqsiuser wrote: |
Could this be a bug or does it work as designed? |
We can never rule out the possibility of a bug, especially as you've not mentioned the version you're running.
One thought that does occur is you say:
mqsiuser wrote: |
I have a flow with an MQInput node and a Timer node
...
I can trigger the flow A SECOND time with putting a message into the "Trigger" queue |
Depending on how exactly you've got that wired up, and exactly how you've got that deployed, it's plausible that the flow has 2 start points and a single instance (additional instance =0) will process both. If you can't run a user trace (urgh!) set off the Timer event and drop 5 messages on the queue. Or set the Timer to go off every second and drop 5 messages on the queue. See how many instances run in the face of all this stimulus. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Nov 13, 2014 6:53 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
The TimeoutNotification node will start an entirely independent thread each time it fires.
A flow with two input nodes, and 0 additional instances of the flow, and 0 additional instances of each node pool will still run two independent threads.
Every input node always gets a single thread.
Again, the best place to solve "duplicate data in the database" is at the database.
If you want to ensure that two threads of a message flow are not running the same piece of code at the same time, like a database insert, you can use an ATOMIC block in ESQL, or similar (a mutex) in Java/.NET. I don't know if you can do that within a Mapping node, nor do I know what the behavior is if you use PROPAGATE within an ATOMIC block. |
|
Back to top |
|
 |
mqsiuser |
Posted: Thu Nov 13, 2014 7:58 am Post subject: |
|
|
 Yatiri
Joined: 15 Apr 2008 Posts: 637 Location: Germany
|
Thank you both !
I am actually missing the ATOMIC block ... ups ...
The flow uses SELECT, CREATE and UPDATE.
I have put ATOMIC blocks now around the CREATE and UPDATE (SELECT should be fine without).
Thanks, I guess this helps / solves the problem  _________________ Just use REFERENCEs |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Nov 13, 2014 8:04 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
mqsiuser wrote: |
I have put ATOMIC blocks now around the CREATE and UPDATE (SELECT should be fine without). |
Again, that does nothing to prevent duplicate data being inserted into the database.
It merely prevents those statements from running in two threads at the same time. |
|
Back to top |
|
 |
mqsiuser |
Posted: Thu Nov 13, 2014 8:54 am Post subject: |
|
|
 Yatiri
Joined: 15 Apr 2008 Posts: 637 Location: Germany
|
The logic is:
Code: |
1. SELECT <1 row (by unique key)>
2. If 'NOT EXISTS' <this 1 row> CREATE (INSERT)
3. If <this1row.someValue> <> <msgTree.someValue> UPDATE <this 1 row> |
With that we had <this 1 row> 2 times in the DB ...
Inserting ATOMIC I get:
Code: |
PROTECT_MY_ROW: BEGIN ATOMIC
1. SELECT <1 row (by unique key)>
2. If 'NOT EXISTS' <this 1 row> INSERT (CREATE)
END (PROTECT_MY_ROW);
3. If <this1row.someValue> <> <msgTree.someValue> UPDATE <this 1 row> |
COMMIT will (likely) be when the flow finishes.
Am I (are we) (still) fine with that? _________________ Just use REFERENCEs |
|
Back to top |
|
 |
|