Skip to content

Savepoints - #1666

Open
doxlik wants to merge 7 commits into
eclipse-vertx:masterfrom
doxlik:savepoints
Open

Savepoints#1666
doxlik wants to merge 7 commits into
eclipse-vertx:masterfrom
doxlik:savepoints

Conversation

@doxlik

@doxlik doxlik commented May 11, 2026

Copy link
Copy Markdown
Contributor

This PR adds API for Savepoints and implementation of it for Postgres client.

Closes #1369

@tsegismont

Copy link
Copy Markdown
Member

Can you please rebase the PR? The unrelated CI failures should be fixed now

@doxlik

doxlik commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@tsegismont rebasing done!

CI still have some failure but seems like it couldn't build in action with Postgres14, not any test problem.
Not sure what is reason for that, seems like it is some maven issue in that particular action.

@tsegismont

Copy link
Copy Markdown
Member

The CI has been stabilized hopefully, would you mind rebasing again? Thank you

@doxlik

doxlik commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

@tsegismont Hi, there were no new commits since the last rebase, so I amended my latest commit to trigger a push. It seems CI is passing now. Looking forward to your review!

Signed-off-by: doxlik <doxlikx@gmail.com>
Signed-off-by: doxlik <doxlikx@gmail.com>
Signed-off-by: doxlik <doxlikx@gmail.com>
Savepoints were implemented for PostgreSQL only. The command itself is
plain SQL, so the remaining drivers mostly need to route SavepointCommand
to a simple query, but they do not all agree on the syntax and two of them
cannot release a savepoint at all.

Driver gains supportsSavepointRelease(). Microsoft SQL Server and Oracle
create savepoints but have no statement that discards one, so releasing on
those drivers fails with an UnsupportedOperationException rather than
pretending to succeed, and the savepoint stays usable for a rollback.

MySQL uses the standard syntax. DB2 requires the mandatory ON ROLLBACK
RETAIN CURSORS clause when a savepoint is created. Transact-SQL names the
statements SAVE TRANSACTION and ROLLBACK TRANSACTION. Oracle runs the
statement on its JDBC connection through a new OracleSavepointCommand.

Generated savepoint names are now VX_SP_<n>: an unquoted Oracle identifier
cannot start with an underscore, so the previous __vx_sp_<n> was invalid
there.

The behaviour every database agrees on moved to TransactionTestBase, gated
on the two capabilities, so each driver inherits it. What the databases do
not agree on stays in the driver tests: PostgreSQL fails the whole
transaction when a statement fails, whereas MySQL leaves the transaction
usable, and MySQLTransactionTest now covers that difference.

Verified against PostgreSQL, MySQL and Oracle. SQL Server and DB2 could not
be started locally, both for reasons unrelated to this change.

Signed-off-by: doxlik <doxlikx@gmail.com>
Removing the duplicated helpers from PgTransactionTest left three imports
behind, and MySQLTransactionTest imported Future without using it, both of
which fail spotless:check.

SQL Server drops a savepoint once the transaction has been rolled back to
it and answers a second rollback with "No transaction or savepoint of that
name was found", so rolling back twice to the same savepoint is now a
capability the drivers report, and SQL Server opts out.

Signed-off-by: doxlik <doxlikx@gmail.com>
@doxlik

doxlik commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

@vietj @tsegismont Hi. I added support for other DBs. Please have a look once you have time.

Whether a failed statement also fails the surrounding transaction was only
covered for PostgreSQL and MySQL, and only MySQL stated it. It is now a
capability the drivers report, statementErrorFailsTransaction(), with a
test for each answer and a third test showing that rolling back to a
savepoint recovers the transaction either way.

The drivers that had no savepoint test of their own get one for the part
that is specific to them: SQL Server that a savepoint does not nest the
transaction, so @@TRANCOUNT stays at one across SAVE TRANSACTION and the
rollback; DB2 that a cursor opened before the savepoint survives the
rollback, which is what ON ROLLBACK RETAIN CURSORS is for; Oracle that a
savepoint leaves the autocommit handling around commit and rollback alone.

Signed-off-by: doxlik <doxlikx@gmail.com>
The connector hands out a pooled connection that is released when the
transaction ends, so closing it again failed the test with "Connection
released twice". Acquire the connection from the pool instead, which is
what proves it went back, and assert on the rows the transaction committed.

Signed-off-by: doxlik <doxlikx@gmail.com>
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.

Support rollback to savepoint after failure

2 participants