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
WriteCommit.parse_job→ ParseJob (0..1)WriteCommit.sync_run→ SyncRun (0..1)WriteCommit.rule_set→ ReconciliationRuleSet (0..1)WriteCommit.user→ User (0..1)
Referenced by
ModelRun.data_seq(1..1)ErasureRequest.executed_in(0..1)MlDatasetVersion.data_seq(1..1)ScoringBatch.data_seq(1..1)RecordRevision.available_in(1..1)RecordRevision.replaced_in(0..1)SystemVersion.created_seq(1..1)SystemVersion.retired_seq(0..1)
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_setand 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_correctionwith 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.