bcquality/custom/knowledge/architecture/log-writes-must-survive-rollback.md
Michael Dieringer d2e2f2adb4 Fredagsregler: tre evidensbaserede tilfoejelser fra ugens haendelser
1. text-artifacts-require-explicit-utf8-handling (Type B): to
   produktionshaendelser, samme sygdom - smiley double-encodet via
   HTTP-streng, og en Mode B-batch der skrev mojibake i tre CLAUDE.md
   fordi PS 5.1 laeser BOM-loese .ps1 som cp1252. Reglen: raa bytes
   ved transfer, eksplicit UTF-8 ved write, tekst-transformation i
   Python, grep for maerket foer commit.

2. log-writes-must-survive-rollback (Type B): fejl-logs skrevet i
   samme transaktion forsvinder ved rollback - loggen mister praecis
   de fejl den findes for. Isoleret session (StartSession -> insert +
   commit) er moensteret. Evidens: Wareco IC web-service-log
   2026-07-02; havde tidligere kostet en udvikler det meste af en dag.

3. Skaerpelse af setup-doc-must-not-reference-unpromoted-stable-files:
   kanal-tilstand verificeres via git (ls-remote/klon), aldrig CDN;
   to sande observationer kan modsige hinanden naar verden flytter
   sig imellem dem - tidsstempl al kanal-evidens. Felt-verificeret
   af Conzept-sessionens selvkorrektion 2026-07-03.

Foerste PR foedt direkte i QualityHub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 19:03:23 +02:00

2.8 KiB

bc-version domain keywords technologies countries application-area
all
architecture
logging
rollback
session
transaction
error-log
web-service
telemetry
al
w1
all

Log writes must survive transaction rollback

Description

The naive instinct when adding logging is to insert the log record inside the running transaction. That log has a fatal blind spot: when the operation ERRORS, the transaction rolls back — and takes the log entry with it. The result is a log that faithfully records every success and silently loses exactly the failures it exists to capture.

Observed in production design (Wareco IC, 2026-07-02): a log of errors and duration per web-service call needed entries to persist even when the business transaction was rolled back. The correct pattern — writing the log from an ISOLATED SESSION so its commit is independent of the caller's transaction — had previously cost a developer most of a day to discover.

Rule

A log whose purpose includes capturing FAILURES must write its entries in a transaction that is independent of the operation being logged:

  1. Isolated session write: start a separate session (StartSession on a codeunit that inserts the log record and commits) so the entry persists regardless of what happens to the caller's transaction.
  2. The log codeunit does ONE thing: insert + implicit commit. No business logic rides along in the isolated session — anything committed there escapes the caller's rollback by design.
  3. Duration/telemetry fields are captured in the caller and passed as parameters — the isolated session must not re-read state that the rollback may erase.
  4. Logs that only record successes (audit of committed work) may stay in the main transaction — this rule targets error/diagnostic logs specifically.

What NOT to do

  • Do not Insert the error-log record in the same transaction as the operation — the error you most need to see is the one that deletes it
  • Do not "fix" it with Commit before the risky call — a stray Commit breaks the caller's atomicity and violates posting-routine rules
  • Do not swallow errors to keep the log alive (if Codeunit.Run then... without re-raising) — the log must observe the failure, not suppress it

Signal to watch for

A log table whose entries are inserted in the flow they measure, with no isolated-session writer — combined with any error path. In review: search callers of the log-insert for surrounding Insert/Post in the same transaction scope.

Message to developer

When an in-transaction error log is found, explain: entries vanish on rollback, so the log is blind to failures; route the write through an isolated session (StartSession → insert+commit codeunit) with values passed as parameters.