Grails save(flush:true)的行为与.save()相同

Grails save(flush:true)的行为与.save()相同,grails,groovy,hql,transactional,Grails,Groovy,Hql,Transactional,我们一直在测试一种不同的储蓄方式。然而,结果并不像我们预期的那样。我们创建了调查方法,每个调查都有多个问题。我们测试了几个案例,它们都以相同的方式提交了查询 @Transactional class Service { Survey createNewSurvey(NewSurveyCommand command) { Survey survey = new Survey() survey.properties[] = command.properties

我们一直在测试一种不同的储蓄方式。然而,结果并不像我们预期的那样。我们创建了调查方法,每个调查都有多个问题。我们测试了几个案例,它们都以相同的方式提交了查询

@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()之间有任何区别(有或没有事务)

有人能解释一下
使用flush保存和
不使用flush保存是如何工作的吗

表示flush(可选)-当设置为true时,将刷新持久性上下文,立即持久化对象。然而,在我们的案例中,我们看到,它并没有像doc说的那样发生。或者我误解了吗?

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日志文件的行

简而言之,GORM/Hibernate会尝试保存所有INSERT/UPDATE语句,直到会话刷新为止。这要么直到您手动调用
.save(flush:true)
,要么会话超出范围(例如,最终控制器呈现/响应)。这是默认行为。以上一切似乎都很正常。你期望发生什么?@Joshuamore,当我在每次保存后放置.save(flush:true)时,我希望数据库日志如下所示。对于每次保存(flush:true),都有一个委员会在docs和my reply尝试中遗漏了关键字。您将无法以如此精确的方式使用
flush:true
控制对数据库的提交级别。这涉及到很多因素,大多数情况下GORM/Hibernate会为您做出最佳选择。因此,您的意思是,每个会话都不会在数据库中创建新的提交。提交由hibernate处理。您尝试了任何提交,但没有发出保存?或者甚至是一个多层事务,其中1调用多个其他事务?通常save()就足够了。在您希望确保更改的半段已通过的特定位置,请使用.withNewTransaction和.save(flush:true)确保已通过。很明显,您没有使用flush:true的要求,因此在您当前的测试范围内,您可以看到在这些情况下,我不得不使用flush:true,以确保它被选中