Skip to content

feat: add NewTxnContext for validated multi-mutation transactions#7

Merged
mlwelles merged 6 commits into
mainfrom
feat/txncontext
Jul 17, 2026
Merged

feat: add NewTxnContext for validated multi-mutation transactions#7
mlwelles merged 6 commits into
mainfrom
feat/txncontext

Conversation

@mlwelles

Copy link
Copy Markdown
Contributor

What

Adds Client.NewTxnContext — a validated, deferred-commit read-write transaction — so callers can run several mutations in one atomically-committed transaction:

  • Upsert(obj, predicates...), Update(obj), Insert(obj)
  • DeleteEdge(uid, predicate, targetUIDs...), DeleteNode(uids...), DeletePredicate(uid, predicate)
  • Commit(), Discard()

Why

The typed write methods (Insert/Upsert/Update) each open a dgman transaction with SetCommitNow(), so they auto-commit per call. A caller that needs to group several mutations into one atomic commit (for example: delete an owner's old edges and nodes, then upsert the owner) cannot express that through the typed API without dropping to raw dgman — which bypasses the client's validation, defaulting, and unique-error translation. NewTxnContext closes that gap.

Behavior

Each staged write runs the same defaulting, validation, and unique-constraint error translation (to *UniqueError) as its single-shot counterpart — it reuses validateStruct, applyDefaults, and parseUniqueError. Nothing reaches the database until Commit() succeeds; Discard() abandons every staged mutation.

Note: unlike the single-shot writes, the transaction path does not run autoSchema schema creation, so a type written only via NewTxnContext must already have its schema applied (documented in the TxnContext godoc).

Tests

txn_test.go covers validation-fires-in-txn, multi-op atomicity, unique-error translation, and DeletePredicate. Unit suite green (plain and -race); the real-Dgraph CI job exercises true deferred-commit rollback that the embedded file engine cannot.

Docs

README gains a section on NewTxnContext next to the atomic-operations docs; CHANGELOG updated for v0.7.0.

mlwelles added 5 commits July 17, 2026 14:53
Insert/Upsert/Update each open a dgman transaction with SetCommitNow and
commit per call, so a caller cannot group several typed mutations into one
atomic commit; consumers that need multi-mutation atomicity drop to raw
dgman and lose validation.

Add TxnContext and client.NewTxnContext, which open one dgman transaction
without SetCommitNow and stage any number of mutations and deletes until
Commit. Each staged Insert/Upsert/Update runs the same pre-mutation pipeline
as the single-shot methods (default population, struct validation) and the
same unique-constraint error translation, so grouping mutations costs no
validation. DeletePredicate emits the n-quad `<uid> <predicate> * .` to clear
a scalar predicate or all edges of a predicate.

The transaction holds a pooled connection for its lifetime and returns it on
Commit or Discard; a deferred Discard after Commit is a safe no-op.
Add embedded-engine (file://) and remote (dgraph://) table-driven tests for
NewTxnContext:

- validation fires inside the transaction and blocks commit
- multi-op DeleteEdge + DeleteNode + Upsert commit together; an error before
  Commit leaves the store unchanged
- a duplicate unique insert returns a typed *UniqueError
- DeletePredicate clears a scalar predicate while the node survives

The dgraph:// cases activate when DGDAO_TEST_ADDR is set. The embedded engine
commits each successful mutation immediately, so the atomicity sibling
triggers a pre-commit error (rejected before any write is applied) to assert
"store unchanged"; true rollback of already-staged valid writes is exercised
by the dgraph:// job.
@mlwelles
mlwelles requested a review from a team as a code owner July 17, 2026 22:13
@mlwelles
mlwelles merged commit 60473ef into main Jul 17, 2026
9 checks passed
@mlwelles
mlwelles deleted the feat/txncontext branch July 17, 2026 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant