Optimistic concurrency control¶
Two people open the same row. Both save. Without a check the second save silently erases the first one. With a version field the second save is refused, and the app can reload and ask.
| Schema | One field with isConcurrencyControlField: true, usually a number stamped by a conversionFun. |
| Checked by | Update by id and replace by id of the schema APIs. Not update many. |
| Refused with | 400 : Concurrency version mismatch in 'version'. This row/document is already updated. |
| From code | g.sys.db.updateById(…) skips the check unless you pass skipConcurrencyControl: false. |
1. Add the version field¶
2. Send it back with every update¶
Read, then update with the version you read
GET /api/schema/admin/mongodb/shop/products/get-by-id/68d...a1
→ { "name": "Mug", "price": 20, "version": 1727683200850 }
PUT /api/schema/admin/mongodb/shop/products/update-by-id/68d...a1
{ "price": 22, "version": 1727683200850 }
→ 200, the row now carries a new version
- The value sent must equal the value stored. Another write in between changed it : the update answers
400with the message above, and nothing is written. Reload the row and try again with its new version. - The field is mandatory in the payload once the row has a version : an update without it is refused the same way.
From your code¶
- Calls made with
g.sys.dbskip the check by default, so a scheduler or an event can update rows without carrying versions. PassskipConcurrencyControl: falsein the parameters to enforce it there too. - The website animates the whole exchange.