Skip to content

Trace SQL transaction control statements and connection wait - #10213

Merged
tim-smart merged 5 commits into
mainfrom
agent/effect-bot/6074d1ecc099
Nov 1, 2026
Merged

tim-smart merged 5 commits into
mainfrom
agent/effect-bot/6074d1ecc099

Conversation

@effect-bot

@effect-bot effect-bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Closes #10203
Closes EFF-3183

Summary

SqlClient.withTransaction ran BEGIN, COMMIT, ROLLBACK and the savepoint statements directly on the connection, so their time showed up only as unexplained time in sql.transaction. Connection acquisition also ran without sql.transaction as its parent span.

makeWithTransaction now does the following. Because the change is in makeWithTransaction, every driver that uses it gets this.

  • Control spans, always traced: each transaction control runs in its own kind: "client" span, explicitly parented to that level's sql.transaction, just as every statement gets a client span.
    • Names are {operation} {target}, using Statement.spanTarget. With no target the name is just {operation}; there is no sql.execute fallback.
    • Operations are BEGIN, SAVEPOINT, COMMIT, ROLLBACK, ROLLBACK TO SAVEPOINT and RELEASE SAVEPOINT. onCommitFailure also appears as ROLLBACK.
    • Each span carries the client's spanAttributes plus db.operation.name, and has no db.query.text.
    • Spans wrap the raw callback, before Effect.orDie and the commit-failure recovery. A failed COMMIT therefore ends its own span with the failure, and transaction semantics don't change.
  • Events removed: the control spans replace the effect.sql.transaction.commit, effect.sql.transaction.savepoint and effect.sql.transaction.rollback events on sql.transaction. Those events had no duration or status, and their timestamps match the start of the new spans. Anything that filters on them will no longer see them. SqlClient is @stability unstable.
  • Acquisition: acquireConnection always runs with Tracer.ParentSpan = sql.transaction. Drivers already gate their connect spans on Statement.SpanPropagationEnabled. With that flag on, PgPool reports a cold transaction's db.connect under the transaction instead of under whatever outer span was current.
  • Wait time, behind the flag: with Statement.SpanPropagationEnabled and TracerTimingEnabled on, a top-level sql.transaction records db.client.connection.wait_time_ms at connection hand-off, before BEGIN. The wait helper Statement already used moved to internal/sql.ts so both modules share it.

Known driver quirks, now visible under normal tracing and left as-is:

  • libsql runs BEGIN inside acquireConnection, so its BEGIN span is empty and its BEGIN time counts as connection wait.
  • When no transaction is active, sqlite's isTransaction cleanup skip produces an empty ROLLBACK span.
  • pg's onCommitFailure ROLLBACK span always succeeds, because that ROLLBACK's error is ignored.

Tests

  • packages/effect/test/sql/SqlClient.test.ts, makeWithTransaction › tracing:
    • span names, parents, kind and attributes;
    • when BEGIN and COMMIT run relative to the body;
    • per-span exits when the body or COMMIT fails;
    • with the flag off: control spans, but no wait time and no events;
    • with tracing off: no spans;
    • acquisition parent, and a wait time that excludes BEGIN.
  • packages/sql/pg/test/PgPool.in-process.test.ts: a cold transaction under an outer span reports db.connect, BEGIN app and COMMIT app under sql.transaction.

Validation

  • pnpm test --run on packages/effect/test/sql/ (78 passed) and PgPool.in-process.test.ts (11 passed).
  • sqlite-node (202) and sqlite-do (20) pass. The d1 suite passes 19/19 when the host isn't overloaded; under high load some of its miniflare tests time out, both with and without this change.
  • pnpm lint, pnpm check and pnpm jsdocs --check are clean.
  • The suites that need Docker databases (pg, mysql, mssql, libsql integration) were not run locally.

Failing tests for EFF-3183 / #10203: control spans for BEGIN, SAVEPOINT,
COMMIT, ROLLBACK, ROLLBACK TO SAVEPOINT and RELEASE SAVEPOINT under
SpanPropagationEnabled, acquisition parented to sql.transaction, and
db.client.connection.wait_time_ms on the transaction span.
With Statement.SpanPropagationEnabled, makeWithTransaction runs each
transaction control in a client span under sql.transaction, parents
connection acquisition to the transaction span, and records the
transaction's connection wait time.
@changeset-bot

changeset-bot Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f4a8b26

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 33 packages
Name Type
effect Patch
@effect/opentelemetry Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-cloudflare Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/ai-typesafe Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/graphql-generator Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@effect-janitor effect-janitor Bot added the 4.0 label Oct 31, 2026
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
arbitrary-combinators.ts 39.41 KB 39.41 KB 0.00 KB (0.00%)
basic.ts 7.23 KB 7.23 KB 0.00 KB (0.00%)
batching.ts 11.08 KB 11.08 KB 0.00 KB (0.00%)
brand.ts 6.87 KB 6.87 KB 0.00 KB (0.00%)
cache.ts 11.54 KB 11.54 KB 0.00 KB (0.00%)
config.ts 22.84 KB 22.84 KB 0.00 KB (0.00%)
differ.ts 22.00 KB 22.00 KB 0.00 KB (0.00%)
http-client.ts 26.93 KB 26.93 KB 0.00 KB (0.00%)
http-router.ts 37.00 KB 37.00 KB 0.00 KB (0.00%)
logger.ts 12.01 KB 12.01 KB 0.00 KB (0.00%)
metric.ts 9.47 KB 9.47 KB 0.00 KB (0.00%)
optic.ts 7.10 KB 7.10 KB 0.00 KB (0.00%)
pubsub.ts 16.02 KB 16.02 KB 0.00 KB (0.00%)
queue.ts 12.82 KB 12.82 KB 0.00 KB (0.00%)
schedule.ts 11.80 KB 11.80 KB 0.00 KB (0.00%)
schema-bigdecimal.ts 14.14 KB 14.14 KB 0.00 KB (0.00%)
schema-binary.ts 41.26 KB 41.26 KB 0.00 KB (0.00%)
schema-class.ts 21.73 KB 21.73 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 29.60 KB 29.60 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 27.99 KB 27.99 KB 0.00 KB (0.00%)
schema-string-transformation.ts 15.35 KB 15.35 KB 0.00 KB (0.00%)
schema-string.ts 12.34 KB 12.34 KB 0.00 KB (0.00%)
schema-template-literal.ts 16.27 KB 16.27 KB 0.00 KB (0.00%)
schema-toArbitrary.ts 38.95 KB 38.95 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 26.15 KB 26.15 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 20.90 KB 20.90 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 21.05 KB 21.05 KB 0.00 KB (0.00%)
schema-toFormatter.ts 21.14 KB 21.14 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 26.17 KB 26.17 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 21.23 KB 21.23 KB 0.00 KB (0.00%)
schema.ts 20.82 KB 20.82 KB 0.00 KB (0.00%)
stm.ts 14.20 KB 14.20 KB 0.00 KB (0.00%)
stream.ts 10.38 KB 10.38 KB 0.00 KB (0.00%)

Control spans replace the effect.sql.transaction.* events under normal
tracing; only the connection wait time stays behind SpanPropagationEnabled.
…on events

Control spans are traced like statements, without SpanPropagationEnabled,
and replace the effect.sql.transaction.* events. The flag still governs
connection wait time and driver span parenting.
@tim-smart
tim-smart merged commit e7a6ea4 into main Nov 1, 2026
17 checks passed
@tim-smart
tim-smart deleted the agent/effect-bot/6074d1ecc099 branch November 1, 2026 22:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sql: give BEGIN, COMMIT, ROLLBACK and savepoint statements their own spans under sql.transaction

2 participants