Failed to commit transaction when rolling back schema changes in Cucumber @After hook
0 reputation · 12 Feb 2025, 02:03 UTC
0 reputation · 12 Feb 2025, 02:03 UTC
When a scenario creates or alters tables in an @Before hook, the test framework often relies on the underlying ORM to begin a transaction and then rolls it back in an @After hook. However, many databases do not support rolling back DDL statements, leading to the documented error Failed to commit transaction when a hook attempts to commit a transaction that was never opened or has already been rolled back.
The main constraints are:
Given these uncertainties, the following questions remain:
@Before hook without triggering a Failed to commit transaction error?@After hook to ensure clean test isolation?34775 reputation · 12 Feb 2025, 10:44 UTC
1. Safest way to revert DDL changes made in a @Before hook without triggering a “Failed to commit transaction” error
COMMIT when a DDL statement runs, so the surrounding transaction is already closed.@After hook run compensating DDL outside any ORM transaction, e.g. DROP TABLE IF EXISTS … or DROP SCHEMA … CASCADE, using a new connection or a connection with auto-commit enabled.2. Cucumber’s built-in support for per-scenario isolated databases
@After, or a transaction-aware ORM that can start a new transaction per scenario and roll it back for DML only.3. Detecting and handling a failed transaction commit in an @After hook
commit() or rollback(), check connection state and auto-commit.Connection conn = dataSource.getConnection();
if (!conn.getAutoCommit() && !conn.isClosed()) {
try { conn.rollback(); } catch (SQLException e) { log.warn("Rollback failed", e); }
}
SQLException and log it. If cleanup cannot be guaranteed, fail the scenario to avoid silent pollution.@Before, execute DDL directly via native query, do not start a transaction.List<String> for the @After hook.@After:
conn.getAutoCommit(); if false, rollback inside try/catch.DROP SCHEMA IF EXISTS test_uuid CASCADE;Confirmed: Cucumber-JVM does not provide built-in per-scenario DB isolation. Confirmed: most relational databases cause an implicit commit on DDL, so a surrounding transaction is ended by the database.
Likely explanation for the error: the ORM attempts to commit or rollback a transaction that is already closed because DDL auto-committed, and the driver reports the commit failure when the hook runs.
Which database and ORM/driver you are using changes the exact compensating DDL syntax and auto-commit behavior. Confirming that will let you choose the correct drop statements and connection handling.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.