Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring @Sql fixtures: decide whether setup commits outside the test rollback

Last updated: 5 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

SQL setup can join a test transaction or commit in an isolated one; the choice changes what survives cleanup and what other connections can see.

Fixture visibility is transactional

A receipt test decorated with @Transactional normally rolls back its work at the end. An @Sql fixture may run inside that transaction when a transaction manager is available. A service invoked on the same thread sees the setup row, but a separate HTTP request or worker connection may not see uncommitted setup. With @SqlConfig(transactionMode = ISOLATED), the script runs in its own transaction and commits before the test. Client versus server transactions determine which mode a live-server test needs.

Own teardown

An isolated fixture will not disappear when the test transaction rolls back. Give each test a unique receipt key, clean it deliberately or reset the disposable database. A cleanup script using isolated mode can run after the test, but it must not delete records still being used by a parallel test. Parallel database isolation is a stronger choice when many tests share one server. Avoid broad DELETE statements against a database that may contain non-test data.

Prove the desired semantics

Run a test that opens another connection and checks whether the fixture is visible before the test ends. Assert the row is gone after rollback for joined fixtures and remains until cleanup for isolated fixtures. The correct mode depends on whether the component under test uses the test thread or a separate transaction. Write that expectation in the test name so a future switch from MockMvc to a socket test does not silently invalidate it.

Implementation contract

Java
@Sql(scripts = "/sql/receipt-seed.sql",
     config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ReceiptHttpFixtureTest {
    // The server request uses another transaction and sees committed seed data.
}

Cost and verification

An isolated script adds a commit and cleanup work. Joined setup is cheaper and rollback-friendly, but cannot serve a different connection until committed.

Common Mistakes

  • Do not expect a server-side request to see uncommitted test-thread setup.
  • Do not expect isolated @Sql data to vanish with the test rollback.
  • Do not share fixed fixture keys across parallel tests without isolation.

Read next

Spring Boot HTTP test: client rollback does not own server writes, Spring Testcontainers parallel tests: one database can leak another test's rows, Spring command rollback test: inspect state after an injected failure, Spring Data JPA test: flush and clear before trusting a read, Spring TestContext cache: keep equivalent tests on one context shape.

spring
spring-testing
sql-test-fixture-transaction-mode
Storage details