Services and Transactions

Site Admin · 11 Sep 2026 · 7 views

What are Services?

Services in Grails encapsulate business logic separate from controllers. They follow a naming convention: a class named BookService in grails-app/services is automatically available as a dependency-injected bean.

Creating a Service

class BookService {

    def createBook(Map params) {
        def book = new Book(params)
        if (!book.validate()) {
            throw new RuntimeException("Validation failed")
        }
        book.save(flush: true)
        return book
    }

    def findBooksByAuthor(String author) {
        return Book.findAllByAuthor(author)
    }
}

Injecting Services into Controllers

Grails uses Spring's dependency injection automatically. Simply declare a property with the service name:

class BookController {
    BookService bookService

    def create() {
        def book = bookService.createBook(params)
        flash.message = "Book ${book.title} created"
        redirect(action: "list")
    }
}

Transactional Methods

Services can be transactional by setting static transactional = true. When enabled, all public methods run within a database transaction:

class BookService {
    static transactional = true

    def transferBook(Long fromId, Long toId) {
        def from = Book.get(fromId)
        def to = Book.get(toId)
        from.delete()
        to.save()
    }
}

If any part of transferBook fails, all changes are rolled back.

Programmatic Transactions

For fine-grained control, use withTransaction:

Book.withTransaction { status ->
    // custom transactional code
}

Key Points

  • Services hold business logic and are auto-injected by name.
  • static transactional = true makes all methods transactional.
  • Transaction rollback happens automatically on exceptions.
  • Use withTransaction for programmatic transaction control.
  • Services keep controllers thin and focused on request handling.
Share this post:

Comments (0)

Please login or register to comment.