Commit 488b66c
`ObjectQL.transaction()` carries two caveats that are part of its DECLARED
meaning (ADR-0119 D1, packages/spec/src/contracts/objectql-engine.ts), not
hidden behaviour: it degrades to no-transaction/no-rollback when the default
driver has no `beginTransaction`, and it covers the DEFAULT datasource only,
so an object routed elsewhere by `setDatasourceMapping` is written outside it.
Declaring them is not the same as being able to observe them, and both were
completely mute. A caller asking for atomicity and not getting it had no way
to find out; a multi-datasource "atomic" unit of work that partially committed
reported nothing — one store reverted, the other kept its rows, and the caller
saw only that the whole thing failed. Same shape as `batchData`'s `atomic`
flag being a lie for as long as it was (ADR-0119 D4).
Behaviour is unchanged. This is the observability half only:
- `warnTransactionUnsupported` — `warn`, once per driver per engine instance,
on the degrade path. Names the driver, the consequence and the fix. `warn`
rather than `error` per AGENTS.md's judgment question: at that moment
nothing has been lost, a capability is simply absent, which is the
`if (!capability)` composition branch that section keeps at `warn`.
- `reportWriteOutsideTransaction` — `error`, once per transaction per
datasource, when an insert/update/delete inside an open transaction resolves
to a driver that transaction does not cover. `error` because afterwards the
system looks entirely normal from the outside while a write it claimed was
part of an atomic unit has landed on its own: the durability class.
- `TransactionScope` on the ambient `txStore` entry records WHICH driver owns
the open transaction. Observability record only — it routes nothing.
Both surfaces report through the same engine-side helpers, so the direct
(`engine.transaction`) and sandboxed (`ScopedContext.transaction`, reached as
`ctx.api.transaction`) paths share one budget and one wording.
Tightening either caveat — an `opts.require` that throws, refusing a
cross-driver write, or an owned-vs-joined signal in the callback signature —
changes the contract's declared semantics and is deliberately NOT done here;
that half of #4619 belongs to `packages/spec`.
Note for #5351: the `TransactionScope.driver` added here is exactly the
"txStore records the owning driver" prerequisite its recommended option A
names. This PR only reports the mismatch; it does not gate the handle.
Claude-Session: https://claude.ai/code/session_01V7WetGmnfoXNn8cLieKKmx
Co-authored-by: Claude <noreply@anthropic.com>
1 parent d8f65fe commit 488b66c
3 files changed
Lines changed: 664 additions & 7 deletions
File tree
- .changeset
- packages/objectql/src
Lines changed: 53 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
0 commit comments