Fco
Fco

Reputation: 195

Why Grails/Spring transactional behavior not working in this case?

I have a grails (2.5.2) app, with a mysql and a NoSQL interaction. There's a main/principal service method that call 2 other methods:

class mainService {

  static transactional = false
  NoSQLDataAccessService noSQLDataAccessService

  // main/principal method
  @Transactional
  void save(json){

    // (1) creating domain entities from json
    addNewDomainEntities(entities)

    // (2)
    noSQLDataAccessService.set(json)
  }

  @Transactional
  void addNewDomainEntities(entities){
  // save the entities in a mysql schema and use save(flush:true) 
  // because i need the generated id's
  }

}

As you can see, this mainService creates new domain entities (1), flushing the session to get the id's. Then, i call other service method (2) that store the json in a NoSQL schema:

class NoSQLDataAccessService(){

  static transactional = false

  void set(json){
    try{
    // save the json in a NoSQL schema
    } catch(Exception ex){
      // if fails, i log the exception and throws it again
      throws ex
    }
  }
}

But, sometimes the noSQLDataAccessService.set() fails by external causes and the entities created before still persist in the mysql db.(this is the problem)

The save method, that contains all this program execution, is marked like @Transactional, so if the noSQLDataAccessService.set() throws an exception, all the changes made should be not applied because the rollback. I'm right?

Upvotes: 0

Views: 198

Answers (1)

augustearth
augustearth

Reputation: 291

You probably have to throw an RuntimeException, not an Exception, to force a rollback as per this StackOverflow conversation. Instead of:

throws ex

you might try:

throw new RuntimeException(ex)

Further, I would recommend you be explicit about your transaction isolation. Perhaps something like:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)

Upvotes: 2

Related Questions