Hosted by:
Unit testing expertise at your fingertips!
Home | Discuss | Lists

Transaction Rollback Pain

John Hurst sent me an e-mail in which he described some of the issues his team had encountered using Transaction Rollback Teardown. He wrote:

We used Transaction Rollback Teardown for our database integration tests for a while, after a discussion on TheServerSide during which Rod Johnson advocated the approach. I gathered his main motivation for using it was for performance, since a rollback is usually a lot faster than re-priming the database in a new transaction for the next test. Indeed, we did find it somewhat faster than our previous approach. We used Spring's excellent AbstractTransactionalDataSourceSpringContextTests base class, which supports most of what you need to do for this pattern out of the box.

However, I chose to abandon this pattern after a few months. Here are the drawbacks I came across with this approach:

  1. You lose some test isolation. In the way we implemented this pattern, anyway, each test assumed the database was in a certain base starting condition, and the rollback would revert it to that condition. In our current model, each test is responsible (usually via a base class's setUp()) for priming the database into a known state.
  2. You can't see what's in the database when something goes wrong. If your test fails, you usually want to examine the database to see what happened. If you've rolled back all the changes, it makes it harder to find the bug.
  3. You have to be very careful not to inadvertently COMMIT during your test. Yes, the code under test has declarative transaction management, and does nothing surprising. But we occasionally would need to do things in the test setup like DROP and reCREATE a sequence to reset its value. This, being DDL, COMMITs any outstanding transaction. Confused programmers.
  4. You can't easily mix in tests that DO need to COMMIT changes. Lately I have added some PL/SQL stored procedures and tests. Some of the stored procs do explicit commits. I cannot mix these in the same JUnit suite with tests that assume the database always remains in a certain state.

I apologise if my terminology isn't consistent with what's in your book. Also, my experience is probably a little limited, since I've only tried this approach in a Spring environment and I prefer to do most things in a "Spring" way. Finally, I am sure these limitations can be and are worked around in various ways. It's just for our team, this pattern turned out to be more trouble than it was worth.

(Don't get me wrong -- I DO think the pattern should be included. I just think the consequences should be noted, and maybe it isn't for everyone.)


John Hurst

Page generated at Wed Feb 09 16:39:03 +1100 2011

Copyright © 2003-2008 Gerard Meszaros all rights reserved

All Categories
Introductory Narratives
Web Site Instructions
Code Refactorings
Database Patterns
DfT Patterns
External Patterns
Fixture Setup Patterns
Fixture Teardown Patterns
Front Matter
Result Verification Patterns
Test Double Patterns
Test Organization
Test Refactorings
Test Smells
Test Strategy
Value Patterns
XUnit Basics
xUnit Members
All "Sidebars"
Class - Instance Duality
Database as SUT API?
Faster Tests Without Shared Fixtures
Testing Stored Procs with JUnit
There's Always an Exception
Transaction Rollback Pain
Unit Test Rulz
Using Delta Assertions to Detect Data Leakage
What's in a (Pattern) Name?
Why Do We Need 100 Customers?