Kan du härleda det, lagra det inte

Någonstans i de flesta affärssystem finns ett tal ingen litar på. Lagersaldot. Kontosaldot. Intjänade poäng. Använda platser. Det är oftast en kolumn som koden skriver till, och vid det andra året är det fel någonstans och ingen kan säga när det gick fel eller varför.

Lösningen är inte bättre validering. Det är att sluta lagra det.

Lagrat kontra härlett

En lagrad summa är ett påstående. Något beräknade den en gång och skrev ner den, och från det ögonblicket kan den glida ifrån de händelser som producerade den - en retry som tillämpades två gånger, en transaktion som havererade halvvägs, en välmenande manuell korrigering, en race mellan två förfrågningar.

En härledd summa är en fråga ställd till händelserna själva. Den kan inte glida, för det finns ingenting separat att glida ifrån. Fråga igen och du får dagens svar ur dagens fakta.

Hur det ser ut i praktiken

I stället för en quantity-kolumn har du en tabell med rörelser: var och en med tecken, oföränderlig, med vem som gjorde den, när och mot vilken referens. Ett lagers saldo är summan av de rörelser som rör det. En korrigering är en ny rörelse i motsatt riktning, aldrig en redigering.

Tre saker följer omedelbart, och de är den verkliga vinsten:

  • Avstämningen upphör att vara en uppgift. Saldot och dess förklaring är samma objekt, så de kan inte motsäga varandra. Det finns ingen månatlig övning i att hitta var talet gick fel.
  • ”Varför har vi elva?” går alltid att svara på. Inte oftast. Alltid. Hela historiken är talet.
  • Ångra blir säkert. Att lägga till inversen lämnar revisionsspåret intakt, medan en radering av originalet förstör beviset för vad som hände.

Det finns en liten fungerande version av det här på fallstudien om klinikerna - bokför en rörelse och se hur summorna räknas om ur loggen, utan att någonting någonstans lagrar en kvantitet.

Invändningen, och det ärliga svaret

”Att summera varje rörelse vid varje läsning kommer att bli långsamt.”

Oftast blir det inte det. Några tusen rörelser är ingenting för en databas med rätt index, och de flesta system som oroar sig för det här har långt färre rader än deras skapare tror.

När det verkligen blir långsamt är svaret en periodisk snapshot - en checkpoint-rad som säger ”vid det här datumet var saldot X” - och du härleder framåt från den senaste. Det är en cache, och den är säker just för att den går att bygga om: radera varje snapshot och systemet vet fortfarande alla rätta svar. I det ögonblick du inte längre kan bygga om den ur händelserna har du gått tillbaka till att lagra, och du har det ursprungliga problemet igen plus extra maskineri.

Var du inte ska använda det

Det här är för saker som räknas och som måste kunna förklaras. Det är onödigt för en visningspreferens, ett utkast eller något där det aktuella värdet är det enda någon någonsin kommer att bry sig om. Event-sourcing för en användares valda tema är inte stringens, det är ceremoni.

Vilken av de två ett visst tal är avgörs under förstudien, inte under bygget - och det är en del av varför det första priset någon ger dig oftast är fel. Det är vad anteckningen om vad en plattform faktiskt kostar handlar om.