Skip to content

6.9.2.1 WriteCommit

6.9.2.1.1 Purpose

One saved change to versioned data, with its write number. The write number is the single clock of the model: reading at a number N sees every write up to N and none after it. Numbers come from a sequence, so writers never wait for each other; the watermark (the highest N below which nothing is still pending) says which N are safe to read.

6.9.2.1.2 Questions it answers

  • Which write made a revision available?
  • Which parse job, sync run, rule set or user made a write?
  • What did the data look like at write number N?
  • Which write number can a reader or a model safely read at right now?

6.9.2.1.3 Fields

Field Type Cardinality Description
seq integer 1..1 Key.
Reserved in its own short transaction before the write starts, so the pending row is visible to everyone while the write is in progress.
committed_at datetime 0..1 Empty while pending or void.
kind enum 1..1 Values: parse, sync_diff, resolution, selection, computation, identity, app_edit, file_removal, erasure, manual_correction.
manual_correction: a correction made by a developer in the Dev ORM of the system (see the note below).
parse_job ParseJob 0..1
sync_run SyncRun 0..1
rule_set ReconciliationRuleSet 0..1
user User 0..1 For edits made in our app (farm.animal_records.edit_own).
status enum 1..1 Values: pending, committed, void. Default: pending.
committed: set in the same transaction as the data it makes available. void: the write was abandoned, by a rollback or an expired lease; it carries no data and the watermark passes it.
lease_until datetime 1..1 A pending write past its lease is set to void by the scheduler; long jobs renew the lease. A writer that finds its own write void must roll back, never commit.
actor string 0..1 The User or MoonitoringUser whose request made the write; empty for a write made by a job.
reason string 0..1 Why the write was made, in a sentence a reviewer can check; required for kind = manual_correction.
access_grant string 0..1 For kind = manual_correction in prod: the id of the approved prod-db-access grant the developer worked under.
created_at datetime 1..1

6.9.2.1.4 Relationships

References

Referenced by

6.9.2.1.5 Rules & constraints

  • One write to versioned data, with its number. Numbers come from a database sequence and may have gaps; what readers see is governed by the watermark (see notes). Replaces the gap-free counter allocated inside the write transaction, which serialised every writer of the farm system on one row lock.
  • Every system keeps its own sequence of WriteCommits in its own database: a system never reads another system's data, so a version stamp (SystemVersion) always points to a write of the system that owns the row.
  • Kind, parse_job, sync_run, rule_set and user are used by farm; another system leaves them empty and records the actor. Watermark and leases work the same everywhere.
  • Dev ORM writes. A developer never changes versioned data with a raw UPDATE or DELETE.
  • The Dev ORM of a system is built from the same commit as the system and writes through the system's own data layer: a correction reserves a WriteCommit of kind manual_correction with the developer as actor, a reason and, in prod, the approved grant; appends a revision to a revision chain (RecordRevision) or a new image to a registry row (SystemVersion); commits; and writes the outbox events the same change would emit through the API, so every cache and consumer sees it. A cancellation is a revision too; removing personal data is an ErasureRequest, never a Dev ORM delete. A table that is not versioned is changed in one transaction, with a PlatformAuditEvent holding the image before and after.
  • The Dev ORM never writes the outbox, the WriteCommits themselves, audit rows, migrations, credentials or keys. In prod it writes only within an approved prod-db-access grant; in stage any staff member it admits may write, with the same WriteCommits and audit, so stage shows what prod would record.
  • Watermark = the highest N such that no write with seq ≤ N is pending. Reads, as-of queries and ModelRun.data_seq (ModelRun) use N ≤ watermark only: there every write ≤ N is committed or void, so "the data at N" never changes again, whatever order the writes committed in. The watermark is computed, not stored.