In FOLIO, most storage modules follow the "last writer wins" strategy for handling record updates. From the end-user perspective this may lead to a situation when a stale record (older version of a record) previously loaded into the UI overrides a more recent version of the record on the server. Hence relevant updates may get lost in the process.
Handling of updates in FOLIO should rely on more explicit semantics, both in the storage (backend) APIs and the way it is communicated to the user through the UI.
From the storage and API perspective there are two major strategies for handling conflicting updates:
- optimistic locking – each record state is marked with a "version number" (or a timestamp, hash, etc) which is returned to the client along with the record. The client includes the version number during the update and the server checks that the version hasn't changed before it writes the record back. If the record is dirty (version doesn't match) the update is aborted. In practice for a REST API (typical FOLIO uses case) this means using ETag with a combination of If-Match conditional request and 412 (precondition failed) and 409 (conflict) error codes.
- pessimistic locking – the record being updated is "locked" until the client completes the update. This means no concurrent updates are possible and ensures the state between the client and server is consistent. It can, however, lead to contention issues and care must be taken to avoid deadlock situation. In practice, this strategy require an explicit "locking API" exposed to client (UI) – the client will need to request and release lock for any record update explicitly.
In general, optimistic locking is used when the risk of collisions (updates to the same record) is low and when the lock granularity is high ((ie duration of any given update is short). The opposite is true for the pessimistic locking strategy.
Also, the impact on the user experience should be taken into account when selecting the appropriate strategy:
- OL means that in certain situations the update operation will fail which needs to be communicated to the user, The UI should then allow the user to choose the next step, e.g by refreshing the state of the record in the browser and re-applying original changes.
- PL means that a particular client (browser) owns an exclusive lock to perform any updates to the record. To avoid contention issues, the lock should include an automatic timeout after whic the lock is automatically released – this should be communicated to the user e.g in form of a timer.