Data plane

Transactions across every provider.

Some providers support 2PC. Some only support local transactions. Some support nothing — Cassandra, Redis, Neo4j cross-session writes. Vadyl picks the right strategy based on declared DbCapabilities, registers compensation for every mutation, and walks the saga LIFO if anything fails partway. You write business logic. Vadyl writes the rollback.

Commit strategy by capability

Pick the strategy from the declared capabilities.

DbCapabilities.Transactions describes what each provider can do — Supports2Pc, SupportsSavepoints, SupportsCompensationOnly. Vadyl reads that, picks the strategy, and never falls back to a weaker mode silently.

Native transactions where possible

Single-provider operations use the provider's native transaction. SQL Server, PostgreSQL, MySQL, MongoDB sessions, Neo4j session-spanning transactions — all real, all participating in Vadyl's lifecycle.

Two-phase commit across providers

When two providers both support 2PC, Vadyl coordinates a real distributed transaction. Prepared phase, commit phase, rollback on any participant failure.

Saga compensation everywhere else

Cassandra has no XA. Redis has no transactional cross-key. Mixed-provider DAGs are the norm. Vadyl registers a compensation for every mutation and walks the saga LIFO on failure.

Saga compensation, deterministic

Priority-LIFO rollback. DELETE → UPDATE → INSERT.

CompensationAction.Priority is the canonical ordering rule: DELETE = 30, UPDATE = 20, INSERT/LINK = 10. Sorted descending, LIFO within priority. Constraint violations during rollback minimized by construction.

Pre-mutation snapshots

WriteCoordinator captures a snapshot WITH the access filter applied — so compensation correctness honors RLS even when restoring deleted rows.

Type-aware re-insert

ForDelete compensation filters out identity columns on re-insert. No identity-insert errors. Provider-specific quoting and casting handled in the AST, not the saga.

Cross-storage compensation

Document writes get DocumentMutationPlan compensation. Graph mutations get UpsertVertex / UpsertEdge inverses. KV writes get KvDelete / KvPut-with-prior-value. All execute through canonical executors.

Cancellation-safe

Rollback uses CancellationToken.None. A cancelled caller token never silently prevents cleanup — anti-pattern #18 codified at every site.

Compensation audit

Every compensation invocation surfaces in the canonical observability relay. The audit trail shows what failed, what compensated, what state the world ended up in.

Saga visibility

Operations expose their compensation chain through the explainability plane. You can ask Vadyl exactly what would roll back if step N fails — before you commit.

Three guarantee tiers

Pick the strictness, see the actual achieved level

Strict

If compensation is unavailable for any step in the operation, Vadyl refuses to start. Deny-by-default for write paths that cannot be made consistent.

Use when correctness > availability

Standard default

If compensation is unavailable, Vadyl proceeds, logs the degradation, increments a metric. vadyl.document_writes.guarantee_degradations.total

The everyday default

BestEffort

Proceeds silently. Use when you've decided availability matters more than guaranteed consistency. Use sparingly — and audit the trail.

Explicit, never the silent default

Every WriteCommitResult reports ActualGuaranteeTier — the achieved level, not the requested one. Honesty over hand-waving.

30/20/10
Priority constants

DELETE / UPDATE / INSERT

LIFO
Within priority

Deterministic, last-in first-out

3
Guarantee tiers

Strict / Standard / BestEffort

0
Silent degradation

Every fall-through is metered + logged

Stop writing manual rollback scripts.

Vadyl tracks every mutation and registers compensation. If step N fails, it walks the saga backwards until the world is consistent. Your code expresses intent. The platform handles consistency.