Handling Update Conflicts

What happens when two users update the same records while offline?
The default is essentially “last write wins”, but this can be customized by the developer.
The change queue on the client stores three types of operations:
  1. 1.
    PUT / Create new row - contains the value for each non-null column
  2. 2.
    PATCH / Update existing row - contains the id, and value of each changed column
  3. 3.
    DELETE / Delete existing row - contains the id
It is up to the app backend to implement these operations and associated conflict handling.
The operations must be idempotent — i.e. the backend may receive the same operation multiple times in some scenarios, and must handle that appropriately.
  • A per-client incrementing operation id is included with each operation that can be used to deduplicate operations, and/or the backend can implement the operations in an idempotent way (e.g. ignore DELETE on a row that is already deleted).
A conflict may arise when two clients update the same record before seeing the other client’s update, or one client deletes the record while the other updates it.
Typically, the backend should be implemented to handle writes as follows:
  1. 1.
    Deletes always win: If one client deletes a row, any future updates to that row are ignored. The row may be created again with the same ID.
  2. 2.
    For multiple concurrent updates, the last update (as received by the server) to each individual field wins.
The server could implement some validations. For example, the server could have a record of orders, and once an order is marked as completed, reject any further updates to the order.
Future versions may include support for custom operations, e.g. “increment column by 1”.
Support for CRDT operations may also be added in the future.