Default Declarative Transactions

Services are typically involved with co-ordinating logic between domain classes, and hence often involved with persistence that spans large operations. Given the nature of services they frequently require transactional behaviour. You can of course use programmatic transactions with the withTransaction method, however this is repetitive and doesn't fully leverage the power of Spring's underlying transaction abstraction.

Services allow the enablement of transaction demarcation, which is essentially a declarative way of saying all methods within this service are to be made transactional. All services have transaction demarcation enabled by default - to disable it, simply set the transactional property to false:

class CountryService {
    static transactional = false
}

You may also set this property to true in case the default changes in the future, or simply to make it clear that the service is intentionally transactional.

Warning: dependency injection is the only way that declarative transactions work. You will not get a transactional service if you use the new operator such as new BookService()

The result is all methods are wrapped in a transaction and automatic rollback occurs if an exception is thrown in the body of one of the methods. The propagation level of the transaction is by default set to PROPAGATION_REQUIRED.

Custom Transaction Configuration

Grails also fully supports Spring's Transactional annotation for cases where you need more fine-grained control over transactions at a per-method level or need specify an alternative propagation level:

import org.springframework.transaction.annotation.*

class BookService {

@Transactional(readOnly = true) def listBooks() { Book.list() }

@Transactional def updateBook() { // … }

}

For more information refer to the section of the Spring user guide on Using @Transactional.

Unlike Spring you do not need any prior configuration to use Transactional, just specify the annotation as needed and Grails will pick them up automatically.