Summary
The row count check (issue #939) is documented as read-only, but on a connection whose autocommit is off it leaves an open transaction behind: its SELECT COUNT(*) queries and the metadata reads behind IDatabaseConnection#createDataSet() are never committed or rolled back.
This is harmless when the connection is closed right after (the pool rolls it back on return), but harmful when the connection outlives the check — shared through a CachingConnectionProvider with DefaultPrepAndExpectedTestCase#setCloseConnectionAfterTest(false). That connection then sits idle in a transaction for the whole test run:
- it holds an
ACCESS SHARE lock on every table it counted, blocking TRUNCATE / ALTER / VACUUM and interfering with other sessions;
- PostgreSQL's
idle_in_transaction_session_timeout terminates it mid-run, after which the next use of the pooled connection fails with EOFException / "An I/O error occurred while sending to the backend".
Reproduced against HSQLDB: RowCountChecker.capture() on an autoCommit=false connection leaves INFORMATION_SCHEMA.SYSTEM_SESSIONS."TRANSACTION" true for that session.
Affected
3.6.0-SNAPSHOT (main) — the row count check integration. Reported from a Spring Batch suite using Agroal (autoCommit=false) + CachingConnectionProvider + closeConnectionAfterTest=false + -Ddbunit.rowCountCheck=true.
Fix direction
RowCountCheck.snapshot() should end its read transaction when the connection's autocommit is off — a rollback, since the snapshot wrote nothing.
Summary
The row count check (issue #939) is documented as read-only, but on a connection whose autocommit is off it leaves an open transaction behind: its
SELECT COUNT(*)queries and the metadata reads behindIDatabaseConnection#createDataSet()are never committed or rolled back.This is harmless when the connection is closed right after (the pool rolls it back on return), but harmful when the connection outlives the check — shared through a
CachingConnectionProviderwithDefaultPrepAndExpectedTestCase#setCloseConnectionAfterTest(false). That connection then sits idle in a transaction for the whole test run:ACCESS SHARElock on every table it counted, blockingTRUNCATE/ALTER/VACUUMand interfering with other sessions;idle_in_transaction_session_timeoutterminates it mid-run, after which the next use of the pooled connection fails withEOFException/ "An I/O error occurred while sending to the backend".Reproduced against HSQLDB:
RowCountChecker.capture()on anautoCommit=falseconnection leavesINFORMATION_SCHEMA.SYSTEM_SESSIONS."TRANSACTION"truefor that session.Affected
3.6.0-SNAPSHOT (
main) — the row count check integration. Reported from a Spring Batch suite using Agroal (autoCommit=false) +CachingConnectionProvider+closeConnectionAfterTest=false+-Ddbunit.rowCountCheck=true.Fix direction
RowCountCheck.snapshot()should end its read transaction when the connection's autocommit is off — a rollback, since the snapshot wrote nothing.