Q15 of 26 · SQL
How are SQL transactions used in automated testing, and what is the benefit of rolling back after each test?
SQLMidsqltransactionsrollbacktest-isolationcleanup
Short answer
Short answer: Wrapping each test in a transaction and rolling it back on teardown is the fastest and cleanest way to reset DB state — the data never persists, so there's nothing to DELETE.
Detail
The pattern:
- BEGIN TRANSACTION before the test's setup
- Run setup SQL (INSERTs, UPDATEs)
- Execute the test action
- Run assertions (SELECTs)
- ROLLBACK — all changes vanish, DB returns to pre-test state
BEGIN;
INSERT INTO users (id, email) VALUES (9999, 'test@example.com');
-- ...test action happens here...
-- Assertions
SELECT COUNT(*) FROM orders WHERE customer_id = 9999; -- expect 1
ROLLBACK; -- nothing persisted, no cleanup needed
Advantages:
- Speed — ROLLBACK is instant; DELETE queries on large tables are slow.
- Isolation — parallel test runs on the same DB can each have their own transaction without colliding (if using row-level locking).
- No orphan data — a test crash before teardown? The DB's crash recovery still rolls back uncommitted transactions.
Limitations:
- Doesn't work if the application code commits its own transactions (the test transaction can't roll back what the app already committed).
- Doesn't work across multiple DB connections (each connection has its own transaction scope).
- Some side effects (sending emails, calling external services) happen outside the DB transaction and can't be rolled back.
In practice, many teams use this pattern in unit/integration tests via frameworks like Spring's @Transactional test support or a direct JDBC/pg wrapper.
// WHAT INTERVIEWERS LOOK FOR
The rollback-for-cleanup pattern, its speed advantage, and its key limitation (app commits its own transactions). Awareness of when it doesn't work.
// COMMON PITFALL
Assuming ROLLBACK can undo everything — it only covers the DB changes within that connection's transaction.