Services are the place in the grails where we write all our data persistence code and business logic. So it is important that these services should be Transactional and they are.

By default all the services in the grails are Transactional, it means all the data persistence code of one service will commit in the database in one attempt. We can change the default transactional behaviour by

  static transactional = false

Then one question: why we use @Transactional annotation in service while they are already transactional?

@Transactional annotation gives us flexibility to make the particular service method Transactional. But if we use @Transactional on any service method then only that method is transactional.

So one more question arise: when a transaction (hibernate transactional) will commit? A transaction will be committed after the last line of the service execution.

Note: What is going on when an exception is occurred in the service code? Will the transaction rollback or commit? It depends upon the exception type.
If the exception is Unchecked Exception then transaction will rollback. If it is Checked Exception then transaction will commit after the exception.

Lets take an example:
Suppose we have a User domain and UserService.

User.groovy

class User {
   String username
   String name
    static constraints = {
        username(nullable: false)
        name(nullable: false)
    }
}

UserService.groovy

class UserService {
   
    //Successfully save the user
    def createFirstUser() {
        User user=new User(username: "neeraj", name: "Neeraj Bhatt")
        user.save()

    }

    //This code throw the Runtime Exception. In this case user will be rollback
    def createSecondUser() throws  Exception{
        User user=new User(username: "parshant", name: "Parshant Gupta")
        user.save()

        //Throwing Runtime Exception
        1/0
    }

    //This code throw the Checked Exception. In this case user will not be rollback
    def createThirdUser() throws Exception{
        User user=new User(username: "manish", name: "Manish Bharti")
        user.save()

        //Throwing Checked Exception
        throw new IOException()
    }
}

when we call these three method of the service in controller then in the database only two rows created in the user table, one for createFirstUser and one for createThirdUser. createSecondUser service is successfully rollback.