Skip to content

Commit 1166dba

Browse files
committed
Proofread
1 parent 4db4e4f commit 1166dba

4 files changed

Lines changed: 36 additions & 28 deletions

File tree

content/en/docs/refguide/runtime/optimistic-locking.md

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,102 +7,110 @@ description: "Describes optimistic locking support."
77
## Introduction
88

99
{{% alert color="info" %}}
10-
This feature is available from Mendix 11.5 and onwards.
10+
This feature is available from Mendix 11.5.0.
1111
{{% /alert %}}
1212

13-
Optimistic locking is a strategy used in concurrent systems to prevent **lost updates** when multiple users or processes try to modify the same piece of data at the same time. The **optimistic** part comes from the assumption that conflicts are rare. Instead of locking the data immediately, it allows multiple users to read and potentially modify the same data concurrently. It checks for conflicts only at the very last moment, when an update is attempted.
13+
Optimistic locking is a strategy used in concurrent systems to prevent lost updates when multiple users or processes try to modify the same piece of data at the same time. Instead of locking the data immediately, and preventing other users from accessing it, optimistic locking allows multiple users to read, and potentially modify, the same data concurrently. In optimistic locking, the assumption is that conflicts are rare, so it checks for conflicts only at the very last moment, when an update is attempted.
1414

1515
If a conflict is detected—meaning someone else has modified the data since you last read it—your update is rejected, and you typically have to re-read the data and try again.
1616

17-
## Project With Optimistic Locking Disabled
17+
You can decide whether optimistic locking is enabled or disabled for your app.
1818

19-
When two modifications are saved, they are applied in the order of processing. Only changed attributes are written to the database. This means that if two objects with disjoint sets of changed attributes are committed, the changes are not overwritten.
19+
## Behavior of App with Optimistic Locking Disabled
2020

21-
For example, if one user commits changes for `AttributeA` and `AttributeB` and another user commits changes for `AttributeB` and `AttributeC` for the same object, then both `AttributeA` and `AttributeC` are committed according to both users' changes. `AttributeB` is committed based on whichever change was committed last.
21+
When two modifications are saved, they are applied in the order of processing. Only changed attributes are written to the database. This means that if the two commits change different attributes or associations of an object, the changes are not overwritten.
2222

23-
## Project With Optimistic Locking Enabled
23+
For example, if one user commits changes for `AttributeA` and `AttributeB` and another user commits changes for `AttributeB` and `AttributeC` for the same object, then both `AttributeA` and `AttributeC` are committed according to both users' changes. `AttributeB` is committed based on whichever change was committed later.
2424

25-
The Mendix runtime implements optimistic locking by introducing a new attribute named `MxObjectVersion` with type `Long` to all entities tracking their version. The `MxObjectVersion` attribute is not write-protected. However, setting this value will **not** result in it being saved to the database. Its current value will be compared with the value for the same record in the database.
25+
## Behavior of App with Optimistic Locking Enabled
26+
27+
The Mendix runtime implements optimistic locking by tracking the version of all objects using the attribute `MxObjectVersion` with type `Long`. Although the `MxObjectVersion` attribute is not write-protected, setting this value will **not** result in it being saved to the database. Its current value will be compared with the value for the same object in the database.
2628

2729
### How to Enable and Use Optimistic Locking
2830

29-
Optimistic locking can be enabled per Mendix application using the `Runtime` tab in the App settings dialog:
31+
You can enable optimistic locking for your Mendix application in the `Runtime` tab in the App settings dialog:
3032

3133
{{< figure src="/attachments/refguide/runtime/optimistic-locking/runtime-settings-dialog.png" >}}
3234

3335
After optimistic locking is enabled, whenever a commit is executed, the Mendix runtime will automatically ensure that the object that is committed was not already changed by another party after the committer retrieved the object.
3436

3537
### New Projects and Migration
3638

37-
In case an existing app already had the `MxObjectVersion` attribute, when optimistic locking is enabled a duplicate attribute will be reported in the Modeler. This must be fixed by renaming the existing attribute to another name. The system attribute cannot be renamed.
39+
If an existing app already has the `MxObjectVersion` attribute, a duplicate attribute will be reported in Studio Pro when optimistic locking is enabled. This must be fixed by renaming the existing attribute to another name. The system attribute cannot be renamed.
3840

3941
### Behavior
4042

4143
The following runtime actions are influenced by optimistic locking:
4244

4345
#### Create Object
4446

45-
Initialize the `MxObjectVersion` attribute to `0`.
47+
Initializes the `MxObjectVersion` attribute to `0`.
4648

4749
#### Commit Object
4850

49-
When the `MxObjectVersion` attribute in the object being committed is different from the value in the database, or the object was deleted from the database, throw a `ConcurrentModificationRuntimeException`. Otherwise, proceed with the commit while incrementing `MxObjectVersion` by one.
51+
When the `MxObjectVersion` attribute in the object being committed is different from the value in the database, or the object was deleted from the database, the runtime throws a `ConcurrentModificationRuntimeException`. Otherwise, it proceeds with the commit while incrementing `MxObjectVersion` by one.
5052

5153
#### Delete Object
5254

53-
When the `MxObjectVersion` attribute in the object being deleted is different from the value in the database, throw a `ConcurrentModificationRuntimeException`. Otherwise, proceed with the delete. If the object was already deleted, no error occurs.
55+
When the `MxObjectVersion` attribute in the object being deleted is different from the value in the database, the runtime throw a `ConcurrentModificationRuntimeException`. Otherwise, it proceeds with the delete. If the object has already been deleted, no error occurs.
5456

5557
## Performance Impact
5658

5759
Because of the version check performed during commit and delete, optimistic locking incurs some minor performance impact.
5860

59-
## Handling Optimistic Locking Errors in Microflows
61+
## Handling Optimistic Locking Errors in Microflows{#microflow-errors}
6062

6163
When an optimistic locking error occurs, the runtime log contains an entry similar to the following:
6264

6365
```
64-
com.mendix.modules.microflowengine.MicroflowException: com.mendix.core.CoreRuntimeException: com.mendix.systemwideinterfaces.MendixRuntimeException: com.mendix.core.CoreException: com.mendix.core.CoreRuntimeException: com.mendix.systemwideinterfaces.MendixRuntimeException: com.mendix.systemwideinterfaces.connectionbus.data.ConcurrentModificationRuntimeException: Object of type 'MyFirstModule.MyEntity' with guid '3940649673949185' cannot be updated, as it is modified by someone else
65-
at MyFirstModule.MyMicroflow (Change : 'Change 'MyEntity'')
66+
com.mendix.modules.microflowengine.MicroflowException:
67+
com.mendix.core.CoreRuntimeException:
68+
com.mendix.systemwideinterfaces.MendixRuntimeException:
69+
com.mendix.core.CoreException:
70+
com.mendix.core.CoreRuntimeException:
71+
com.mendix.systemwideinterfaces.MendixRuntimeException:
72+
com.mendix.systemwideinterfaces.connectionbus.data.ConcurrentModificationRuntimeException:
73+
Object of type 'MyFirstModule.MyEntity' with guid '3940649673949185' cannot be updated, as it is modified by someone else at MyFirstModule.MyMicroflow (Change : 'Change 'MyEntity'')
6674
```
6775

6876
The above error shows that there was a `ConcurrentModificationRuntimeException` during execution of the change action `Change 'MyEntity'` of the microflow `MyFirstModule.MyMicroflow`. The object had the id `3940649673949185` and was of type `MyFirstModule.MyEntity`.
6977

70-
Once a commit of an object causes an optimistic locking error, trying to commit the same object without reloading will always result in an optimistic locking error.
78+
If committing an object causes an optimistic locking error, trying to commit the same object without reloading always results in an optimistic locking error.
7179

72-
If the changes are still deemed valid, the action causing the optimistic locking error should be retried:
80+
If the changes are still deemed valid, you can retry the action causing the optimistic locking error by doing the following:
7381

74-
1. Change the error handling for that action to either `Custom with Rollback` or `Custom without Rollback`, and do the following steps in the error flow
75-
2. If `$latestError/ErrorType` is `com.mendix.systemwideinterfaces.connectionbus.data.ConcurrentModificationRuntimeException`
76-
3. Retrieve a fresh copy of the object from the database
77-
4. Apply the original changes onto the retrieved copy
78-
5. Invoke the operation again
82+
1. Change the error handling for that action to either `Custom with Rollback` or `Custom without Rollback`, and do the following steps in the error flow.
83+
2. If `$latestError/ErrorType` is `com.mendix.systemwideinterfaces.connectionbus.data.ConcurrentModificationRuntimeException`.
84+
3. Retrieve a fresh copy of the object from the database.
85+
4. Apply the original changes onto the retrieved copy.
86+
5. Perform the operation again.
7987

80-
An example can be seen below. The change action has error handling `Custom without Rollback`. If an optimistic locking error is detected, the object is reloaded from the database, changes are applied again and the change action is retried.
88+
You can see an example implementation in the image below. The change action has error handling `Custom without Rollback`. If an optimistic locking error is detected, the latest version of the object is retrieved from the database, changes are applied again, and the change action is retried.
8189

8290
{{< figure src="/attachments/refguide/runtime/optimistic-locking/retry-example.png" >}}
8391

8492
Check the [documentation](https://docs.mendix.com/refguide/error-handling-in-microflows/) about error handling to find more information about differences between `Custom with Rollback` and `Custom without Rollback`.
8593

8694
## Handling Optimistic Locking Errors in Java Actions
8795

88-
In Java actions an optimistic locking error can be handled by similar steps described in [Handling Optimistic Locking Errors in Microflows]. However, the `com.mendix.systemwideinterfaces.connectionbus.data.ConcurrentModificationRuntimeException` exception will not be the top level exception thrown by the Mendix runtime. It will be wrapped in another exception, so the `cause` chain of caught exceptions should be inspected.
96+
You can handle optimistic locking errors in Java actions using similar steps to those described in [Handling Optimistic Locking Errors in Microflows](#microflow-errors). However, the `com.mendix.systemwideinterfaces.connectionbus.data.ConcurrentModificationRuntimeException` exception will not be the top level exception thrown by the Mendix runtime. It will be wrapped in another exception, so you need to inspect the `cause` chain of caught exceptions.
8997

9098
## Handling Optimistic Locking Errors in the Client
9199

92-
If the optimistic locking error is propagated to the client, then an error dialog is shown as follows:
100+
If the optimistic locking error is propagated to the client, then you will see the following error: "The data you're trying to save has already been modified by another user. Please refresh the page and try again."
93101

94102
{{< figure src="/attachments/refguide/runtime/optimistic-locking/optimistic-locking-error-dialog.png" >}}
95103

96-
To handle the optimistic locking error one of the following approaches can be used:
104+
You can implement one of the following approaches to handle the optimistic locking error:
97105

98106
### Single `Save` Button
99107

100108
In this case the user can refresh the whole page, but this causes all their changes to be lost.
101109

102110
### `Save` Button With a Separate `Refresh` Button
103111

104-
A separate `Refresh` button that retrieves the latest object state from the database and applies the original changes to the retrieved object. After clicking the `Refresh` button, the user can inspect the latest state and can click the `Save` button again. This would be similar to a single retry from [Handling Optimistic Locking Errors in Microflows].
112+
Add a separate `Refresh` button that retrieves the latest object state from the database and applies the original changes to the retrieved object. After clicking the `Refresh` button, the user can inspect the latest state and can click the `Save` button again. This would be similar to a single retry from [Handling Optimistic Locking Errors in Microflows](#microflow-errors).
105113

106114
### Custom `Save` Button
107115

108-
A custom `Save` button that retries saving object using similar steps described in [Handling Optimistic Locking Errors in Microflows], to retry until successful.
116+
Implement a custom `Save` button that retries saving object using similar steps described in [Handling Optimistic Locking Errors in Microflows](#microflow-errors), to retry until successful.
-24.9 KB
Loading
-12.9 KB
Loading
-135 KB
Loading

0 commit comments

Comments
 (0)