How to implement synchronous locking in a microflow?

0
In a microflow I retrieve an entity, change it and write it back. I want to avoid a concurrent user from doing the same. How to do that? In other words I want retrieve-change-commit to be atomic with no other user doing the same at the same time as another user. Example: similar use case to a deli customer number machine: only only customer at a time should have access to pull a ticket. Other customers must queue up behind current customer. Another example: I read the current counter, say 64, add one to get 65 and write it back. If another user reads at the same time she also gets 64  and also adds one and writes (or overwrites) 65. Problem is TWO users end up with SAME counter, 64. Not good! How to provide synchronous boundaries on retrieve-change-commit to something like startTransaction-retrieve-change-commit-endTransaction ? Does Mendix support that? I read the Mendix DOES NOT start a transaction on a Retrieve. Should I insert an unneeded commit first to nudge Mendix to begin a transaction?
asked
3 answers
3

If you need semaphore functionality (MF's queue up before the semaphore and only one by one they are allowed to pass) to prevend critical sections executed in parallel by different threads, Mendix does not support that out-of-the-box. The "Disallow concurrent MF execution" does not give that functionality. The Java synchronisation and locking facility also does not give that functionality, because this only works in Java code and not on MF's.

There are two options:

1 – Create semaphore functionality in Java yourself (java.util.concurrent.Semaphore). Make two Java actions to acquire and release the semaphore. In the MF acquire the semaphore before the critical section and release after. You have to guarantee a release (proper exception handling), otherwise you have a deadlock.
Important: this only works within one JVM. In the case of horizontal scaling and multiple JVM's it does not work. Even so the Disallow concurrent MF does not work in that scenario either.

2 – In scenario of horizontal scaling you need the database to help with this. It is more expensive in performance, but is the only way to guarantee thread synchronisation over JVM's. An update to the same record will hold any other update to that same record by other database sessions (from other threads) until commit or rollback. Also the uniqueness constraint when creating the same unique value will hold any other session from creating.  These properties of the database you can use to acquire and release a lock.

You could also look for “Pessimistic locking” module in appstore if you need another functionality of locking, a signalling to other users that same data is under maintenance by somebody else.

 

answered
0

Hi Richard,

It is possible to disallow concurrent execution of a microflow. More information about that:
https://docs.mendix.com/refguide/microflow#3-concurrent-execution-properties
“the user receives a message or another microflow is executed instead.”

I hope this helps!

answered
0

How about the process queue, that should be able to deal with a First-in-first-out mechanism by assigning a process to a single threaded queue.

You could also try to build something using the Java action commit in separate transaction from the community commons that way the number update can be commited at the beginning of the microflow.

answered