With current web applications architecture it is complicated to track what users are doing on browser side: are they still online or on the way to take a cup of coffee? Will they save a record or just checking it?
We can’t just lock records in the Web Application every time when someone have opened it for editing.
So here we have 2 main problems:
- You don’t know who and when will save it
- You don’t know if user still online or not
In Acumatica we have designed the platform in the way to not depend on user behavior. But we still have 2 different ways to manage concurrent update that we can choose based on type of data:
- Editing of Independent Single record – where data is not frequently edited by multiple users.
- Use of “Optimistic Concurrency Control” technic
- Concurrent Update of Shared record – where data that expected to be updated simultaneously by many users.
- Use of “Calculation Rules” instead of value replacement
Optimistic Concurrency Control
With this approach transactions does not lock resources assuming that they can frequently complete without interfering with each other. But before committing to the database, each transaction must verifies version of the record to make sure that is is not changed by anyone else.
Here you can see the flow:
Version control in Acumatica is done using field “TimeStamp (or Tstamp)” in the Database table.
When Acumatica saves data, it makes sure that version is not changed comparing to time where record was cached:
UPDATE <Table> SET … WHERE TimeStamp <= @P0
Th version is stored in “Graph.Timestamp” property and Primary Record field.
By default Acumatica checks the version only for primary record, by in case needed you can activate checking for each details record as well with RecordComesFirst flag.
This is rarely needed but very important if you have a scenario where single detail record can be edited as detail in several different places with different parents
To Activate version concurrent control you simple need to do two things: Add Timestamp column to the database table, add Timestamp field to the DAC with PXDBTimestampAttribute declared on it. Than it is it, you can now try to update same record from different tabs or browser.
Calculation Rules for Shared Records
Lets assume that we have a record that is frequently updated. Than if we use approach above we have to read old value, change it, than save back to database. But who will be right if we do this simultaneously?
|3/26/2018 5:21 PM
In the case here answer will be – who saves fierst. But this is not nice for the second users to redo the operation again, right?
Due this this problem Acumatica has invented an alternative approach of managing records that can be frequently updated – Instead of tracking TimeStamp we add the calculation rules on the field:
Update Policy: 10 – 4 + 12 = 18
So we send data to the database with updating it using difference and not an absolute value. We also ignore version of the record:
UPDATE <Table> SET <Field> = <Field> + 12 WHERE ... GO UPDATE <Table> SET <Field> = <Field> - 4 WHERE ... GO
This approach is implemented by PXAccumulatorAttribute. This attributes intercept logic of record creation and bypass version check with timestamp field. In the same time it can define update and init rules for shared fields that significantly speed up system performance as we don’t need to wait for locks release.
This kind of approach is very powerful but usually is needed only in some rare case of additional module development. In this case you can read more about Accumulator Attribute in T200 training guide and Acumatica Help.
Hope it helps!