Spring – How to rollback nested transactions with Propagation.REQUIRES_NEW in integration tests

hibernateintegration-testingrollbackspringtransactions

I have several integration tests for various services that extend the following baseclass:

@ContextConfiguration(locations="classpath:applicationContext-test.xml")
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
@Transactional
public abstract class IntegrationTestBase extends AbstractTransactionalJUnit4SpringContextTests
{
    //Some setup, filling test data to a HSQLDB-database etc
}

For most cases this works fine, but I have a service class which has transactions defined with propagation=Propagation.REQUIRES_NEW. It seems these transactions are not rolled back (because they are nested transactions and apparently commit within the "outer" transaction?). The "outer" (test-case level) transaction is rolled back, at least according to test logs. The committed transactions mess up some later tests, because they have changed the test data.

I can get around this by forcing the test to re-create and re-populate the database between tests, but my question is, is this expected behavior or am I doing something wrong in my tests? Can the nested transaction be forced to rollback from the testing code?

Best Answer

This is expected behaviour, and is one of the main reasons to use REQUIRES_NEW :

  • be able to rollback the new transaction, but commit the outer one
  • be able to commit the new transaction, but rollback the outer one

re-populate the database between tests is probably the best solution, and I would use this solution for all the tests: this allows tests to check that everything works correctly, including the commit (which could fail due to flushing, deferred constraints, etc.).

But it you really want to rollback the transaction, a solution would be to add a boolean argument rollbackAtTheEnd to your service, and rollback the transaction if this argument is true.

Related Topic