You can use MDrivenServer concurrency features to protect multi-user updates and serialize business operations, such as assigning a unique registration number, when concurrent execution must not produce the same result.
Choose the concurrency mechanism
Concurrency means that more than one user or process can work with related data at the same time. Choose the mechanism based on whether you need to detect conflicting updates or ensure that one operation executes at a time.
| Need | Use | Example |
|---|---|---|
| Detect conflicting updates in a multi-user application | MDriven Framework PersistenceMapper optimistic locking and CRUD operations in transactions | Two users change the same business object. Optimistic locking is available through the PersistenceMapper interface. |
| Ensure that a critical operation is serialized | A server-side asynchronous job through DoAsync
|
Two users create a Car at the same time. Number assignment must not give both cars the same registration number. |
| Route updates in a Master/Slave deployment | MDrivenServer Master/Slave handling | An update submitted to a Slave is rerouted to the Master, which creates the commit-block for the update. |
Serialize a unique-number assignment
Use a serialized server-side job when an operation must never run concurrently with another instance of the same operation. The following pattern assigns a unique registration number to a Car.
- Move the existing number-assignment expression from the Car state entry action into a method on
Car, for exampleActuallyAssignNewNumber. - Change the state entry action to call the method asynchronously:
self.DoAsync('ActuallyAssignNewNumber')- Upload the model to MDrivenServer.
- Create Cars from two separate server contexts, for example two browser sessions. Save both Cars and wait for the registration number to return from the server.
- Verify that the Cars do not receive the same number.
In this example, DoAsync('ActuallyAssignNewNumber') moves execution to the server. The number is returned after the server has completed the job.
Do not rely on an in-client calculation when the result must be unique across concurrent users. In the Car example, two separate clients can otherwise calculate and assign the same next number before either update has established the required ordering.
Inspect asynchronous work
Use the MDrivenServer administration UI to inspect the asynchronous-job pattern after testing it.
- Open Running, then Data in A0. Select
SysAsyncTicket, then select Search to inspect ticket data such asCar.ActuallyAssignNewNumber.
Master/Slave deployments
When you scale MDrivenServer with Master and Slave nodes, keep the Master and Slaves on the same model version. MDrivenServer persists a model checksum with each commit-block. If a Slave receives a commit-block created with a different model checksum, it requests the required model from the Master, evolves its database, and then applies the commit-block.
For updates submitted to a Slave, MDrivenServer reroutes the updating call to the Master. The Master creates the commit-block, and the Slave applies it. This design keeps the commit-block information in the same database transaction as the business-data update.
