Skip to content

fix(jdbc): rotate the baton before checking endTransaction errors (#98) - #122

Merged
magnusp merged 1 commit into
mainfrom
fix/i98-baton-rotation
Oct 22, 2026
Merged

magnusp merged 1 commit into
mainfrom
fix/i98-baton-rotation

Conversation

@magnusp

@magnusp magnusp commented Oct 22, 2026

Copy link
Copy Markdown
Owner

Fixes #98

Contract

Hrana 3 is the source of truth for transport, values, and metadata. java.sql is the source of truth for the JDBC surface. xerial/sqlite-jdbc is a behavioral reference and conformance foundation, never a copy target.

Protocol basis. Hrana over HTTP PipelineRespBody carries a fresh baton in every response, including a response whose results contain a StreamResultError. The client must consume that baton before inspecting the results.

Change

LibsqlConnection.endTransaction now calls updateStreamState(resp) immediately after the pipeline returns, before any result inspection, matching beginTransaction and executeStatement. The two ad hoc baton assignments in the re-begin error branches are gone because the state is already current there.

LibsqlConnectionTest's scripted client now issues a fresh baton per response and throws on a reused baton, so it behaves like sqld. The new case fails a COMMIT, rolls back, and runs another statement.

TransactionLifecycleIT replays the issue against real sqld with a deferred foreign key.

Red evidence

Base dea07fa, with the new tests applied and production code unchanged.

  • ./mvnw -pl libsql-jdbc test -Dtest=LibsqlConnectionTest: 13 run, 3 errors, each stale baton baton-2 raised by the scripted client from endTransaction. Log /tmp/xerial-parity-i98/lane-1-trunk.log.
  • ./mvnw -pl libsql-itests -am verify -Dit.test=TransactionLifecycleIT: failedCommitCanBeRolledBackAndTheConnectionStaysUsable errors at rollback() with SQL HTTP error 400: Received a baton that has already been used. Log /tmp/xerial-parity-i98/lane-2-trunk.log.

Green evidence at head 7c9d889

  • Focused LibsqlConnectionTest: 13/13, BUILD SUCCESS.
  • libsql-jdbc suite: 190/190.
  • itests: 22/22, TransactionLifecycleIT 4/4, including the failed COMMIT then ROLLBACK case.
  • Conformance: BUILD SUCCESS, 115 run, 1 skipped.
  • xerial control profile: BUILD SUCCESS, 100 run, 1 skipped.
  • spotless:check: no violations.
  • ./mvnw test: BUILD SUCCESS.
  • package -DskipTests: the driver jar builds.
  • Perf: wall clock of ./mvnw -pl libsql-jdbc test, 3 runs per side interleaved. Trunk median 2089 ms, head median 2083 ms.

Divergence

None in behavior. The baton rotation rule has no xerial analog because the reference driver is in-process, so there is no reference note beyond this protocol obligation.

Base dea07fa, head 7c9d889.

@magnusp
magnusp merged commit 2c83a84 into main Oct 22, 2026
4 checks passed
@magnusp
magnusp deleted the fix/i98-baton-rotation branch October 22, 2026 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failed COMMIT or ROLLBACK leaves a stale baton, so the transaction cannot be rolled back

1 participant