190
Views
3
Comments
How do I prevent multiple users from updating the same record at the same time
Application Type
Traditional Web

Hi,

The first problem is: I’m building an application on which multiple users can edit the records. To prevent user from editing at the same time I want to give read only rights if someone else is already editing. I just can quite wrap my head around how to do this. To prevent other users from never being able to edit, because the first one who has editing rights fell asleep behind his desk, I would also like that after 5 minutes of inactivity the first user is kicked out, so others can edit. 

The second problem I have is that a product can only be in one list at the time. So if multiple people are editing different lists, I want the first one to select the item to be able to add it to his list and the other people to get a warning that the product was already selected by another user. 

To make it more clear I will give an example. Say I have an application on which you can make grocery shopping lists. To these shopping lists I can add specific products. For example apples, bananas, pancakes, bread and eggs. A product can only belong to one shopping list. This means that if I select bananas in shopping list 1, I cannot select it for the other lists. 

Problem 1:

-User A is editing list 1

-User B also wants to edit list 1

-How do I make it so that user B just has read only right to list 1. 

Problem 2: 

-User A is editing list 1, at the same time that user B is editing list 2.

-The apples are not yet in any list and so they can be selected by user A or B

-User A selects the apples and user B selects the apples

-This gives an error as the apples are now in lists 1 and 2

I already read the How To Handle Concurrent Updates on Application Data Records - OutSystems. But I am still struggling. 

I hope I made my problems clear, if anything is not clear please say so. 

Kind regards 


2020-09-21 11-35-56
Sachin Waghmare

Hello Anna,

Have you read this documentation? It might help you to find the way you are looking for.

https://success.outsystems.com/Documentation/How-to_Guides/Data/How_To_Handle_Concurrent_Updates_on_Application_Data_Records?

Thanks & Kind Regards,

Sachin

UserImage.jpg
Anna Voskuilen

I already read that documentation, but I'm still struggling 

2020-09-15 13-07-23
Kilian Hekhuis
 
MVP

Hi Anna,

Unfortunately, this is a complex topic, and any solution has its advantages and drawbacks, depending on the scenarios you want to cover.

Basically, any solution that's watertight must rely on a single access provider. In the case of OutSystems software, it's easiest to use the database for that. The GetXxxForUpdate Entity Actions (where Xxx is the Entity name) locks the record that is retrieved until a Commit happens on that record (either explicitly or implicitely). Any other code that tries to perform a GetXxxForUpdate will be blocked until the record becomes available again.

So as a solution, you could create a single "access entity" that can hold multiple records, each for a specific app or area where exclusivity is needed (an entity that you have bootstrapped so the records are available).

So for your Problem 1, in which two users want to access the same data, you perform a GetXxxForUpdate on a specific record of the "access entity". Next you check if the information in that record allows you to proceed. If so, you store information in the record so that anyone else trying to access it will know it's yours, then perform a UpdateXxx Entity Action, optionally followed by a CommitTransaction if you want to do more stuff in the same Action (so blocked users won't have to wait too long). If User B tries to access the screen after User A, they will be informed that User A is already editing that information, and you can force read-only mode, or redirect to another page, or whatever action you think is appropriate. After saving the data and navigating away from the Screen, the code must release User A's claim on the data, by updating again the "access entity", so that any further users can access the data.

The downside to the above is of course when User A just closes their browser so that their claim to the data is never released (that is, the "access entity" still contains their claim, so that other users can't access the data). One solution could be a time-out on the claim - if it's older than a specific time (typically a little over the normal time a user would need to edit and save the data), a User B gets access anyway even if the "access entity" shows User A has access, overwriting User A's claim. When User A is about to save the data, again a GetXxxForUpdate is done and the code checks whether User A is still the one with access. If another user has access, it shows an error message to User A, and they must start over. If no user has access, it can save the data, then relinquish the lock by a commit (either explicitly or implicit by navigating away from the Screen) - note that it may be needed to inform User A the data was update since they accessed the Screen, and they might want to revisit their changes, etc.

Problem 2 is not an access problem, but a resource problem: you have a limited amount of resources. The solution to this is somewhat simpler, as you don't need additional entities to lock. When saving, you can simply perform a GetXxxForUpdate on the record keeping track of how many apples there are, check whether there's still enough, and if so subtract the number of apples requested from the total, and save. If there's not enough it means someone else already placed an order using the apples, and you show an error message to the user, without saving.



Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.