Federico Pedemonte's Blug: because my life would be empty without bugs!

A few day ago I was writing a financial service involving several related domain classes. Under some circumstances I wanted the entire transaction to rollback.

According to the documentation, a Grails transaction is rolled back whenever a RuntimeException is thrown during its execution (this is the default behaviour in Grails, but you can configure it to rollback a transaction for whatever exception you want).

When I finished I wrote some integration tests to make sure that everything worked as expected.

It didn’t.

Basically, the exceptions were thrown but the transactions were never rolled back. It tooks me a lot of hours to understand why.

Let’s show it with an example. Just say we have the ubiquitous Book and Author domain classes:

As we said, every service method call is bounded in its own transaction, unless it is already inside a transaction. That is the case when the integration test class declares to be transactional with the default line:

static transactional = true

indeed, if you change it with:

static transactional = false

the test will pass.

What does this change implies for your test class? It implies that test methods are no more wrapped in transactions and automatically rolled back, so you’ll have to take care of cleaning the house after every test!