How to implement record locking in Wicket
The concept of record locking is useful when you want to allow only one user to edit a data record at a time. A data record or, record for short, can be any collection of data. For example, a user profile, a purchase order, or a data-entry form. In a multi-user environment, you want to avoid the case where multiple users are simultaneously editing the same record and possibly overwriting each other’s changes.
So what we want to do is build a mechanism for controlling access to a record. It’s helpful to see it in action first:
The general flow looks like this:
- A user comes to record A and obtains an editing lock on the record.
- Another user comes to record A but will be unable to make changes until the first user leaves. The first user will be informed to finish their changes and leave the record so that another user can make their changes.
- Once the original user leaves, the second user will be notified that they can begin with their changes.
The main components
The main libraries we will use are:
- wicket-native-websocket-javax – See the official Wicket documentation for adding WebSocket support to your application.
- Redis – Using the awesome Redisson library for Java. We will use Redis topics, one for each record, to notify all listeners of the record when other users enter or leave the record.
Now let’s take a high-level look at the components involved:
- LockablePage – All web pages that want to be lockable will implement this interface which gives them gives them the functionality via composition, without having to write much code.
- LockingService – Contains methods for obtaining and removing locks on records.
- EditRecordPage – Sample page for editing a record that implements LocakablePage and shows simple messaging about the editability and current locks for the record.
- LockingWebSocketBehavior – A WebSockets behavior that is responsible for notifying the specific Redis topic that a new user has started viewing the record or has left the record. It will also update parts of the UI when it receives events.
- RemoveLockPage – Will be invoked on window.onbeforeunload to remove the users’ lock on the record when they leave. This is a safety measure in case the lock is not removed upon closing the web socket connection.
About the demo
There is too much code to go thru all of it here. However I want to point out some notable things.
To simplify the demo, we get the user ID from the query string in EditRecordPage. However, in a real application, you would use the currently logged in user’s ID from your authentication provider.
In a real application, instead of EditRecordPage, you might have an edit user profile page or edit the purchase order page. In each respective case, the ‘record ID’ would be the user ID and the purchase order ID. The implementation will remain the same, both pages will implement LockablePage.
Hopefully the code is understandable enough! Find the full source code on GitHub.