How to force non-parallel execution of code

0
We need some form of locking/syncing on an entity. From what I understand Mendix does (currently?) not have an out of the box implementation for this, so you have to create your own implementation. Assume an Balance and Mutation entity, when processing a Mutation entity we need to check if the Balance is sufficient for the Mutation to be processed. So we do the next steps: 1. Validate the Mutation against the Balance 2. Change the Balance 3. Commit both objects   I was first thinking to put the steps in one MF and set the "Disallow concurrent execution" to "Yes". Although this will enforce the data to stay correct, it will raise unnecessary errors when any concurrent execution is performed. So I am thinking of creating a java action in which I do the steps in  a synchronized block. Thereby preventing any parallel execution of the code. A disadvantage will be that we need to use the custom action to execute the steps and can not enforce this behavior in the domain model. I also looked at using the acquire and releaselock methods from the community commons, in the before and after commit of the entity. This would better prevent any developer from forgetting to use the locking functions. But this will also throw unnecessary errors when 2 processes try to get the same lock. Next to this, our environment is currently running on 2 instances. If I am correct this would mean that any of the above implementations would not work correctly. Does anyone have any advise or experience with these kind of situations? Thanks in advance.
asked
3 answers
1

In the past I had a project with the locking mechanisme allthough without multiple instances. But the WaitForLock action comes in real handy because it would retry to get a lock if a record was already locked by another process . The drawback of this kind of locking mechanisme is when the development team has multiple developers. Because ALL the change actions should always first retrieve a lock. That can easily be forgotten. But apart from that the locking mechanisme worked perfectly.

Regards,

Ronald

 

answered
1

" Next to this, our environment is currently running on 2 instances. If I am correct this would mean that any of the above implementations would not work correctly. "

Indeed, that's an issue. I remember a presentation at a Mendix meetup where they solved this problem using Redis. I assume that's only a feasible solution when you are not running in the Mendix cloud.

A solution would be to make one of you nodes responsible for handling all transaction handling in this domain (you are in fact creating a microservice, you might even consider making it a seperate application for clarity). If you handle everything that needs to be synchrnized on the same node, then you are off course free to use any in memory locking mechanism.

If you end up implementing your own mechanism, the community commons locking mechanism is a good starting point. Luckily this is a fairly standard problem in software development, so there should be enough good resources available.

answered
0

Hi,

one approach I found is to actually let the database handle the locking for you.

To do this you need an additional Attribute on your $Balance that is used for locking. In a microflow you can then

1. Change the $Balance/Locking attribute (with commit)

2. retrieve the Balance object again from database and work with that.

Step 1 can only be finished, when other transactions writing to this object are finished

Step 2 asserts that you get the correct Balance object in case it was changed by a concurrent action.

answered