configuration/principle/data/transaction.data.json

configuration/principle/data/transaction.data.json is a file in GovLab Context. 556 lines of code and 0 definitions.

{
    "category": "Transactions / State / Concurrency",
    "check": {
        "population": "every multi-step write, shared mutable state and retried side effect",
        "freshness": "a verdict stands until the write path, the isolation level or the concurrency model changes",
        "refusal": "the transaction or concurrency test fails a write path that loses an update, commits partially or repeats an effect",
        "observation": "outcomes of concurrent and retried runs, plus the transaction boundaries read from source",
        "evidence": "none: the catalog states this check as a class, so a watched run belongs to each system that adopts it",
        "authority": "the transaction boundary and the isolation level, which every write path conforms to"
    },
    "records": [
        {
            "id": "idempotency",
            "name": "Idempotency",
            "aliases": ["Idempotence"],
            "definition": "A design rule that repeating an operation with the same input has the same effect as running it once.",
            "type": "principle",
            "scope": [
                "API",
                "command",
                "message handler"
            ],
            "requires": ["Idempotency Key or Deterministic Operation"],
            "reinforces": [
                "Retry Safety",
                "Event-Driven Architecture"
            ],
            "enables": ["Safe Retries"],
            "conflicts_with": ["Non-Repeatable Side Effects"],
            "tensions_with": ["State Tracking"],
            "violated_by": [
                "lexicon:non-idempotent-operation",
                "lexicon:duplicate-side-effects"
            ],
            "detected_by": ["side-effectful handlers without deduplication"],
            "measured_by": ["duplicate-effect defect rate"],
            "refactored_by": [
                "lexicon:idempotency-key",
                "architecture:idempotent-consumer"
            ],
            "enforced_by": [
                "retry tests",
                "API policy"
            ],
            "severity": "mandatory",
            "exemplar": {
                "before": "app.post(\"/foo\", async request => fooStore.create(await request.json()));",
                "after": "app.post(\"/foo\", async request => {\n  const key = requireHeader(request, \"Idempotency-Key\");\n  const body = await request.json();\n  return idempotency.execute(key, () => fooStore.create(body));\n});",
                "lang": "ts"
            }
        },
        {
            "id": "atomicity",
            "name": "Atomicity",
            "definition": "A design rule that the steps of a state change either all take effect or none do.",
            "type": "principle",
            "scope": [
                "transaction",
                "operation",
                "workflow"
            ],
            "requires": ["Transaction Boundary"],
            "reinforces": [
                "Consistency",
                "Correctness"
            ],
            "enables": ["All-or-Nothing State Change"],
            "conflicts_with": ["Partial Commit"],
            "tensions_with": ["Distributed Scalability"],
            "violated_by": ["lexicon:partial-commit"],
            "detected_by": ["multi-step writes without transaction/compensation"],
            "measured_by": ["partial failure rate"],
            "refactored_by": [
                "lexicon:introduce-transaction-boundary",
                "architecture:saga-pattern",
                "architecture:compensating-transaction"
            ],
            "enforced_by": ["transaction tests"],
            "severity": "mandatory",
            "exemplar": {
                "before": "await fooStore.remove(from, foo.id);\nawait fooStore.add(to, foo.id);",
                "after": "await database.transaction(async tx => {\n  await tx.foos.remove(from, foo.id);\n  await tx.foos.add(to, foo.id);\n});",
                "lang": "ts"
            }
        },
        {
            "id": "acid",
            "distinctFrom": [
                {
                    "id": "lexicon:base-eventual-consistency",
                    "reason": "ACID keeps each transaction atomic, consistent, isolated and durable, while BASE favors availability and lets replicas converge later."
                }
            ],
            "name": "ACID",
            "aliases": ["Atomicity, Consistency, Isolation, Durability"],
            "definition": "A conceptual representation of the four guarantees of a database transaction: atomicity, consistency, isolation and durability.",
            "type": "model",
            "scope": [
                "database",
                "transaction"
            ],
            "requires": [
                "Atomicity",
                "Consistency",
                "Isolation",
                "Durability"
            ],
            "reinforces": ["Correctness"],
            "enables": ["Strong Transactional Guarantees"],
            "conflicts_with": [],
            "tensions_with": [
                "Distributed Availability",
                "BASE/Eventual Consistency"
            ],
            "violated_by": ["lexicon:partial-commit"],
            "detected_by": ["non-transactional multi-write invariants"],
            "measured_by": ["transactional invariant defects"],
            "refactored_by": [
                "lexicon:introduce-transaction-boundary",
                "lexicon:invariant-check"
            ],
            "enforced_by": [
                "DB transactions",
                "isolation tests"
            ],
            "severity": "contextual",
            "exemplar": {
                "before": "await fooDb.write(foo);\nawait barDb.write(bar);",
                "after": "await database.transaction({ isolation: \"serializable\" }, async tx => {\n  await tx.foos.save(foo);\n  await tx.bars.save(bar);\n  assertInvariant(foo, bar);\n});",
                "lang": "ts"
            }
        },
        {
            "id": "transaction-boundary",
            "distinctFrom": [
                {
                    "id": "lexicon:consistency-rules",
                    "reason": "A transaction boundary fixes which writes one transaction covers, while consistency rules are the invariants it must keep inside that scope."
                }
            ],
            "name": "Transaction Boundary",
            "definition": "A rule or precondition that a transaction covers exactly the writes of one unit of work inside one service.",
            "type": "constraint",
            "scope": [
                "unit of work",
                "aggregate",
                "service"
            ],
            "requires": ["Consistency Rules"],
            "reinforces": [
                "Atomicity",
                "Unit of Work"
            ],
            "enables": ["Safe State Mutation"],
            "conflicts_with": ["Hidden Distributed Transaction"],
            "tensions_with": ["Large Transaction Scope"],
            "violated_by": ["lexicon:hidden-distributed-transaction"],
            "detected_by": ["transaction scope leakage"],
            "measured_by": ["transaction size/duration"],
            "refactored_by": [
                "lexicon:restrict-exports",
                "architecture:saga-pattern"
            ],
            "enforced_by": ["transaction policy"],
            "severity": "mandatory",
            "exemplar": {
                "before": "await beginTransaction();\nawait controller.parse(request);\nawait service.validate(foo);\nawait repository.save(foo);\nawait commitTransaction();",
                "after": "async function createFoo(input: CreateFoo) {\n  const foo = validateFoo(input);\n  return database.transaction(tx => new FooRepository(tx).save(foo));\n}",
                "lang": "ts"
            }
        },
        {
            "id": "unit-of-work-pattern",
            "name": "Unit of Work Pattern",
            "definition": "A design pattern that collects the changes of one use case and commits them together in a single transaction.",
            "type": "pattern",
            "aliases": ["Unit of Work"],
            "scope": [
                "application service",
                "persistence"
            ],
            "requires": ["Transaction Boundary"],
            "reinforces": [
                "Atomicity",
                "Consistency"
            ],
            "enables": ["Coordinated Persistence"],
            "conflicts_with": ["Scattered Save Calls"],
            "tensions_with": ["Repository Complexity"],
            "violated_by": ["lexicon:scattered-save-calls"],
            "detected_by": ["multiple independent saves in one use case"],
            "measured_by": ["save coordination defects"],
            "refactored_by": [],
            "enforced_by": ["persistence conventions"],
            "severity": "recommended",
            "exemplar": {
                "before": "await fooRepository.save(foo);\nawait barRepository.save(bar);\nawait eventRepository.save(event);",
                "after": "const uow = unitOfWork.begin();\nuow.foos.save(foo);\nuow.bars.save(bar);\nuow.events.append(event);\nawait uow.commit();",
                "lang": "ts"
            }
        },
        {
            "id": "consistency",
            "distinctFrom": [
                {
                    "id": "architecture:correctness",
                    "reason": "Consistency is stored data satisfying its invariants, while correctness is code behavior matching its specification."
                },
                {
                    "id": "architecture:fault-tolerance",
                    "reason": "Consistency is data keeping its invariants, while fault tolerance is operation continuing through component failure."
                },
                {
                    "id": "architecture:interoperability",
                    "reason": "Consistency is data inside one system keeping its invariants, while interoperability is separate systems exchanging data."
                },
                {
                    "id": "lexicon:always-fresh-reads",
                    "reason": "Consistency is invariants holding after every change, while always-fresh reads is every read seeing the latest write."
                },
                {
                    "id": "lexicon:availability",
                    "reason": "Consistency is data keeping its invariants, while availability is the system answering at all."
                },
                {
                    "id": "lexicon:durability",
                    "reason": "Consistency is invariants holding after a change, while durability is a committed change surviving a crash."
                },
                {
                    "id": "lexicon:maintainability",
                    "reason": "Consistency is a property of stored data, while maintainability is a property of the code that changes it."
                },
                {
                    "id": "architecture:scalability",
                    "reason": "Consistency is invariants holding, while scalability is performance holding as load grows."
                },
                {
                    "id": "lexicon:operational-complexity",
                    "reason": "Consistency is invariants holding, while operational complexity is the effort of running the system in production."
                },
                {
                    "id": "lexicon:quality",
                    "reason": "Consistency is one property of stored data, while quality is how far a system meets all its expectations."
                },
                {
                    "id": "lexicon:security",
                    "reason": "Consistency is data keeping its invariants, while security is protection from misuse and attack."
                },
                {
                    "id": "lexicon:simplicity",
                    "reason": "Consistency is invariants holding, while simplicity is the absence of unneeded structure."
                }
            ],
            "name": "Consistency",
            "definition": "The degree to which stored data satisfies its invariants after every change.",
            "type": "quality-attribute",
            "scope": [
                "data",
                "transaction",
                "distributed system"
            ],
            "requires": [
                "Invariant",
                "Validation"
            ],
            "reinforces": ["Correctness"],
            "enables": ["Reliable State"],
            "conflicts_with": ["Inconsistent Replicas/Models"],
            "tensions_with": [
                "Availability",
                "Latency"
            ],
            "violated_by": ["lexicon:reachable-invalid-state"],
            "detected_by": [
                "data anomalies",
                "failed invariant checks"
            ],
            "measured_by": ["consistency violation count"],
            "refactored_by": [
                "lexicon:invariant-check",
                "lexicon:introduce-transaction-boundary",
                "lexicon:reconciliation-job"
            ],
            "enforced_by": [
                "database constraints",
                "invariant tests"
            ],
            "severity": "mandatory",
            "exemplar": {
                "before": "foo.total = foo.items.reduce((sum, item) => sum + item.value, 0);\nfoo.itemCount = externalCount;",
                "after": "function rebuildFoo(items: readonly FooItem[]): Foo {\n  return { items, total: sum(items), itemCount: items.length };\n}\nconst foo = rebuildFoo(items);",
                "lang": "ts"
            }
        },
        {
            "id": "isolation",
            "name": "Isolation",
            "definition": "A rule or precondition that concurrent transactions do not see each other's uncommitted changes, to the degree the isolation level declares.",
            "type": "constraint",
            "scope": [
                "database",
                "transaction",
                "concurrency"
            ],
            "requires": ["Concurrency Control"],
            "reinforces": ["Correctness"],
            "enables": ["Safe Concurrent Operations"],
            "conflicts_with": ["Dirty Reads/Writes"],
            "tensions_with": ["Throughput"],
            "violated_by": ["lexicon:dirty-reads-writes"],
            "detected_by": [
                "concurrency tests",
                "isolation anomalies"
            ],
            "measured_by": [
                "anomaly rate",
                "lock contention"
            ],
            "refactored_by": [
                "architecture:pessimistic-locking",
                "lexicon:transaction-isolation-level"
            ],
            "enforced_by": [
                "DB isolation",
                "concurrency tests"
            ],
            "severity": "contextual",
            "exemplar": {
                "before": "const foo = await fooStore.find(id);\nfoo.count += 1;\nawait fooStore.save(foo);",
                "after": "await database.transaction({ isolation: \"serializable\" }, async tx => {\n  const foo = await tx.foos.lock(id);\n  await tx.foos.save({ ...foo, count: foo.count + 1 });\n});",
                "lang": "ts"
            }
        },
        {
            "id": "concurrency-control",
            "name": "Concurrency Control",
            "definition": "A mechanism that coordinates concurrent access to shared state, through locks, versions or compare-and-swap.",
            "type": "mechanism",
            "scope": [
                "transaction",
                "memory",
                "distributed system"
            ],
            "requires": ["Shared State Identification"],
            "reinforces": [
                "Isolation",
                "Correctness"
            ],
            "enables": ["Safe Parallel Mutation"],
            "conflicts_with": [
                "Race Conditions",
                "Lost Update"
            ],
            "tensions_with": ["Performance"],
            "violated_by": ["lexicon:race-conditions"],
            "detected_by": [
                "race detectors",
                "flaky concurrent tests"
            ],
            "measured_by": [
                "race count",
                "contention"
            ],
            "refactored_by": [
                "architecture:pessimistic-locking",
                "lexicon:make-immutable",
                "architecture:optimistic-locking"
            ],
            "enforced_by": [
                "thread-safety analysis",
                "tests"
            ],
            "severity": "mandatory",
            "exemplar": {
                "before": "const foo = await fooStore.find(id);\nawait fooStore.save({ ...foo, count: foo.count + 1 });",
                "after": "await fooStore.update(id, current => ({\n  ...current,\n  count: current.count + 1,\n}), { expectedVersion: foo.version });",
                "lang": "ts"
            }
        },
        {
            "id": "optimistic-locking",
            "name": "Optimistic Locking",
            "aliases": ["Own-Span Compare-and-Swap"],
            "definition": "A design pattern that checks a record's version when it is written and rejects the write if another writer changed it first, comparing only the writer's own span where a surface is fenced per writer.",
            "type": "pattern",
            "scope": [
                "persistence",
                "transaction"
            ],
            "requires": ["Version Field"],
            "reinforces": ["Concurrency Control"],
            "enables": ["Conflict Detection"],
            "conflicts_with": ["Blind Overwrite"],
            "tensions_with": ["Retry Complexity"],
            "violated_by": ["architecture:lost-update"],
            "detected_by": ["updates without version check"],
            "measured_by": ["conflict/retry rate"],
            "refactored_by": [],
            "enforced_by": [
                "repository rules",
                "integration tests"
            ],
            "severity": "contextual",
            "exemplar": {
                "before": "await fooTable.update({ id: foo.id, name: foo.name });",
                "after": "const updated = await fooTable.update({\n  id: foo.id,\n  expectedVersion: foo.version,\n  next: { ...foo, version: foo.version + 1 },\n});\nif (!updated) throw new ConflictError(foo.id);",
                "lang": "ts"
            }
        },
        {
            "id": "pessimistic-locking",
            "name": "Pessimistic Locking",
            "definition": "A design pattern that locks a record before reading it for update, so other writers wait until the transaction ends.",
            "type": "pattern",
            "scope": [
                "persistence",
                "critical section"
            ],
            "requires": ["Lock Ownership"],
            "reinforces": ["Isolation"],
            "enables": ["Strong Conflict Prevention"],
            "conflicts_with": [],
            "tensions_with": [
                "Deadlocks",
                "Latency",
                "Lock-Free Throughput"
            ],
            "violated_by": ["lexicon:blind-overwrite"],
            "detected_by": ["concurrent update conflicts"],
            "measured_by": ["lock wait/deadlock rate"],
            "refactored_by": ["lexicon:apply-concurrency-control"],
            "enforced_by": ["transactional tests"],
            "severity": "contextual",
            "exemplar": {
                "before": "const foo = await fooTable.find(id);\nawait fooTable.save(change(foo));",
                "after": "await database.transaction(async tx => {\n  const foo = await tx.foos.findForUpdate(id);\n  await tx.foos.save(change(foo));\n});",
                "lang": "ts"
            }
        },
        {
            "id": "state-isolation",
            "name": "State Isolation",
            "definition": "A design rule that each piece of mutable state belongs to one unit of concurrent execution, so no two units that run at the same time can write it.",
            "type": "principle",
            "scope": [
                "function",
                "component",
                "service"
            ],
            "requires": [
                "Encapsulation",
                "Ownership"
            ],
            "reinforces": [
                "Predictability",
                "Concurrency Safety"
            ],
            "enables": ["Testability"],
            "conflicts_with": ["Shared Mutable State"],
            "tensions_with": ["Data Sharing"],
            "violated_by": ["lexicon:global-mutable-state"],
            "detected_by": [
                "static mutable fields",
                "shared caches without ownership"
            ],
            "measured_by": ["global state count"],
            "refactored_by": [
                "lexicon:encapsulate-state",
                "lexicon:pass-context-explicitly",
                "lexicon:make-immutable"
            ],
            "enforced_by": [
                "lint rules",
                "architecture tests"
            ],
            "severity": "mandatory",
            "exemplar": {
                "before": "const globalFooState: Foo[] = [];\nfunction addFoo(foo: Foo) { globalFooState.push(foo); }",
                "after": "class FooSession {\n  #state: Foo[] = [];\n  add(foo: Foo) { this.#state = [...this.#state, foo]; }\n  snapshot() { return [...this.#state]; }\n}",
                "lang": "ts"
            }
        },
        {
            "id": "controlled-side-effects",
            "name": "Controlled Side Effects",
            "definition": "A design rule that mutation, I/O and persistence happen at declared boundaries, around a core of pure functions.",
            "type": "principle",
            "scope": [
                "function",
                "module",
                "boundary"
            ],
            "requires": ["Effect Boundaries"],
            "reinforces": [
                "Predictability",
                "Testability"
            ],
            "enables": ["Pure Core / Imperative Shell"],
            "conflicts_with": [
                "Action at a Distance",
                "Hidden Side Effect"
            ],
            "tensions_with": ["Performance Optimization"],
            "violated_by": ["architecture:hidden-side-effect"],
            "detected_by": ["side effects in domain/pure functions"],
            "measured_by": ["side-effect boundary violations"],
            "refactored_by": [
                "lexicon:make-effects-explicit",
                "lexicon:separate-query-from-command"
            ],
            "enforced_by": [
                "effect linting",
                "layer rules"
            ],
            "severity": "recommended",
            "exemplar": {
                "before": "function calculateFoo(foo: Foo) {\n  foo.count += 1;\n  fooLog.record(foo);\n  fooDb.save(foo);\n  return foo.count;\n}",
                "after": "function nextFoo(foo: Foo): Foo { return { ...foo, count: foo.count + 1 }; }\nasync function applyFoo(foo: Foo, store: FooStore, log: Log) {\n  const next = nextFoo(foo);\n  log.write(next);\n  await store.save(next);\n  return next;\n}",
                "lang": "ts"
            }
        },
        {
            "id": "petri-nets",
            "name": "Petri Nets",
            "definition": "A conceptual representation of concurrent flow as places holding tokens and transitions that consume and produce them, which can be analyzed for deadlock.",
            "type": "model",
            "scope": [
                "concurrency",
                "workflow",
                "verification"
            ],
            "requires": ["Places and Transitions"],
            "reinforces": [
                "Concurrency Correctness",
                "Deadlock Freedom"
            ],
            "enables": [
                "Concurrent-Flow Modeling",
                "Reachability and Deadlock Analysis"
            ],
            "conflicts_with": ["Ad-Hoc Lock Ordering"],
            "tensions_with": ["Modeling Overhead"],
            "violated_by": ["lexicon:ad-hoc-lock-ordering"],
            "detected_by": ["deadlocks or lost tokens found only at runtime"],
            "measured_by": ["unreachable or deadlock-prone markings"],
            "refactored_by": [],
            "enforced_by": ["concurrency model review"],
            "severity": "contextual",
            "exemplar": {
                "before": "acquire(a); acquire(b); work(); release(b); release(a);",
                "after": "const net = petriNet({\n  places: { idle: 1, aHeld: 0, bHeld: 0 },\n  transitions: [\n    { name: \"takeA\", consume: { idle: 1 }, produce: { aHeld: 1 } },\n    { name: \"takeB\", consume: { aHeld: 1 }, produce: { bHeld: 1 } },\n  ],\n});\nassertNoDeadlock(reachableMarkings(net));",
                "lang": "ts"
            }
        }
    ]
}