Grails .save(flush: true) 的行为与 .save() 相同
Grails .save(flush: true) behaves the same with .save()
我们一直在测试一种不同的保存方式。然而,结果并不像我们预期的那样。我们有创建调查的方法,每个调查都有多个问题。我们测试了几个案例,它们都以相同的方式提交了查询。
@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 } }
第二次删除事务并保存而不刷新
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 } }
第三个和第四个,一次有交易,一次没有交易。
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 } }
最后从 MySQL 日志中,我们检查了无论我们做了什么,所有的插入都发生在一次提交中。
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
最后我们没有看到 .save(flush: true, failOnError: true), save()(有或没有 Transactional)之间有任何区别。
谁能解释一下 save with flush
和 without flush
是如何工作的?
Grails doc 表示 flush(可选)- 当设置为 true 时会刷新持久性上下文,立即持久化对象。然而,在我们的案例中,我们看到,它并没有像医生所说的那样发生。还是我理解错了?
save()
没有 flush: true
不启动数据库连接。调用 save() 后,数据仅保存在 Hibernate 会话中。因此,在您的情况下,您不会在 MYSQL 日志文件中找到任何相关行。
save(flush: true)
立即在数据库级别启动事务。 所以在第一次调用 save(flush: true)
之后,您应该已经在 MYSQL 日志文件,可能类似于:
Query SET autocommit=0
Query insert into survey (version, brand ,...)
在第二次调用 save(flush: true)
之后,事务将在数据库级别继续(不会再次启动,因此两次保存之间不会发生 COMMIT
)。您还可以看到添加到 MYSQL 日志文件中的行。
我们一直在测试一种不同的保存方式。然而,结果并不像我们预期的那样。我们有创建调查的方法,每个调查都有多个问题。我们测试了几个案例,它们都以相同的方式提交了查询。
@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 } }
第二次删除事务并保存而不刷新
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 } }
第三个和第四个,一次有交易,一次没有交易。
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 } }
最后从 MySQL 日志中,我们检查了无论我们做了什么,所有的插入都发生在一次提交中。
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
最后我们没有看到 .save(flush: true, failOnError: true), save()(有或没有 Transactional)之间有任何区别。
谁能解释一下 save with flush
和 without flush
是如何工作的?
Grails doc 表示 flush(可选)- 当设置为 true 时会刷新持久性上下文,立即持久化对象。然而,在我们的案例中,我们看到,它并没有像医生所说的那样发生。还是我理解错了?
save()
没有 flush: true
不启动数据库连接。调用 save() 后,数据仅保存在 Hibernate 会话中。因此,在您的情况下,您不会在 MYSQL 日志文件中找到任何相关行。
save(flush: true)
立即在数据库级别启动事务。 所以在第一次调用 save(flush: true)
之后,您应该已经在 MYSQL 日志文件,可能类似于:
Query SET autocommit=0
Query insert into survey (version, brand ,...)
在第二次调用 save(flush: true)
之后,事务将在数据库级别继续(不会再次启动,因此两次保存之间不会发生 COMMIT
)。您还可以看到添加到 MYSQL 日志文件中的行。