Determining unique number with concurrent use

3
In a Mendix application for a customer, I have to determine a unique number for an entity. It needs to be based on the next available number in an external system, which I select using an SQL query using a Java action. Eventually, this object data (including the unique number) is synchronized with the external system. However, because multiple users are working with the application concurrently, a situation occurred recently where a duplicate number was selected, causing an error in the external system. I'm thinking of solving this problem by using the 'disallow concurrent execution' option. I've isolated the logic determining the unique number in a single microflow, which retrieves the entity with the highest number, selects the next available number after this highest number using SQL, creates a new object in Mendix with the new (presumably unique) number and commits the object (in Mendix). I've set the Disallow property of this microflow to True and entered an error message. This microflow is used in 2 other microflows, which both have the Disallow property set to False (the default). What will happen if 2 concurrent users execute 1 of these 2 'parent' microflows? Will the whole microflow 'chain' be rolled back? In other words, does the use of Disallow = True in the 'child' microflow prevent this situation?
asked
2 answers
2

When disallow concurrent execution is set to true, the microflow won't execute but it doesn't mean everything else will be rolled back. You can also choose to execute another microflow.

However I would try to solve this problem in the other system, it should not give out the same id twice if it also requires that the id's are unique. A simple select query might not be enough to solve this, you could consider atomically increasing and returning an id with a function or stored procedure.

I'm assuming your application is the only one requesting id's from the other application, because otherwise this whole thing wouldn't work anyway.

If changing the other system isn't possible I'm sure you could work something out, you could locally keep a static synchronized id and either atomically increase it there or at least check for equality after you retrieved an id from the other system. If your application is the only one requesting id's then I don't really see a reason to query the other system for every single id anyway.

If that doesn't work then you could disallow concurrent execution and perhaps create another microflow with a java action and poll the other microflow with a small delay until execution succeeds.

answered
1

Hi Jonathan My guess is that in your situation, where the action is initiated from the client, not from a scheduled event, that the disallow concurrent execution option may only apply to the current client. That is it will stop a single user running it twice concurrently, but will not stop other users from running at the same time. Perhaps someone from Mendix can confirm or correct this.

In situations like this, I normally rely on logic on the external system to get a unique number similar to the Mendix autonumber attribute. I generate a UID (perhaps using RandomHash from Community Commons module) and submit a new record with the UID in one of the fields to the external system, which allocates the unique number to the new record. I then retrieve the number allocated using the UID as a query. If logic is in place on the external system to prevent duplicates, then I will always get the correct number. HTH

answered