Reputation: 1962
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?
Upvotes: 2
Views: 2810
Reputation: 66
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.
Upvotes: 5