Skip to main content
Every mutation is a serializable transaction. A mutation that reads a document and then writes it can’t race another mutation: if the document changes underneath it, Bijection retries the mutation against the new value. You don’t need a version field to keep a mutation correct. A stale edit is a different problem. It happens between mutations, while a person looks at a form:
  1. Ana opens a note.
  2. Ben opens the same note, changes it and saves.
  3. Ana saves the text she started from, and Ben’s change is gone.
Both saves are valid transactions, so the database has nothing to object to. Only your app knows that Ana’s save was based on an old copy. If two people can edit the same record, keep a version field and make each save say which version it started from. If only one person edits a record, or the last save should win, you don’t need any of this.

Add a version field

Store a counter on the document. Classify it like the table’s other fields:
bijection/schema.ts
Start it at 0 when you insert the document.

Compare it in the mutation

The client sends the version it read. The mutation compares it with the stored version, and the transaction guarantees that nothing changes between that check and the write:
bijection/notes.ts

Handle the error in the client

Pass the version the editor opened with, not the latest one from useQuery. A live query updates while the form is open, so reading the version at save time would hide the change you want to catch:
src/EditNote.tsx
When the save fails, show the person the latest text and let them decide what to keep. Don’t retry with the new version automatically: that brings back the overwrite this check exists to stop.