简体   繁体   中英

Grails .save(flush: true) behaves the same with .save()

we have been testing a different way of saving. However, the results weren't as we expected. We have create-survey method, and each survey has multiple questions. We tested few cases and they all committed the queries the same way.

@Transactional class Service {
      Survey createNewSurvey(NewSurveyCommand command) {
       Survey survey = new Survey()
       survey.properties[] = command.properties
       survey.save(flush: true, failOnError: true)  //save survey and flush
       for (NewQuestionCommand questionCommand : command.questions) {
           Question question = new Question()
           question.properties[] = questionCommand.properties
           question.save(flush: true, failOnError: true)  // save each questions and flush
       }
       return survey    } }

The second removing transactional and saving without flush

 class Service {
      Survey createNewSurvey(NewSurveyCommand command) {
       Survey survey = new Survey()
       survey.properties[] = command.properties
       survey.save()  //save survey and flush
       for (NewQuestionCommand questionCommand : command.questions) {
           Question question = new Question()
           question.properties[] = questionCommand.properties
           question.save()  // save each questions and flush
       }
       return survey    } }

The 3th and 4th, once with transactional and once without transactional.

class Service {
          Survey createNewSurvey(NewSurveyCommand command) {
           Survey survey = new Survey()
           survey.properties[] = command.properties
           survey.save()  //save survey and flush
           for (NewQuestionCommand questionCommand : command.questions) {
               Question question = new Question()
               question.properties[] = questionCommand.properties
              survey.addToQuestions()
    }
           survey.save(flush: true, failOnError: true)
           return survey    } }

In the end from MySQL log, we checked that no matter we did all the inserting happened within one commit.

    Query    SET autocommit=0
    Query    insert into survey (version, brand ,...)
    Query    insert into question (version,..d)
    Query    insert into question (version,..d)
    Query    commit
    Query    SET autocommit=1

In the end we didn't see any difference between .save(flush: true, failOnError: true), save() ( with or without Transactional).

Could anybody explain how are save with flush and without flush working.?

Grails doc says that flush (optional) - When set to true flushes the persistence context, persisting the object immediately. However, in our case we saw, it didn't happen as in doc says. Or did I misunderstand it?

save() without flush: true doesn't start the database connection . After calling save() data is only persisted in Hibernate session. So in your case, you would not find any related lines in MYSQL log file.

save(flush: true) starts the transaction on database level immediately. So after calling save(flush: true) for the first time you should already see some lines in your MYSQL log file, probably sth like:

Query    SET autocommit=0
Query    insert into survey (version, brand ,...)

After calling save(flush: true) for the second time the transaction is being continued (not started again, so no COMMIT will happen between two saves) on database level. You can also see lines added to your MYSQL log file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM