2017-07-25 385 views
2

表现相同,我们一直在测试不同的保存方式。但是,结果并不如我们预期的那样。我们有创建调查方法,每个调查都有多个问题。我们测试了几个案例,他们都以相同的方式提交了这些查询。Grails .save(flush:true)与.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 } } 

这是第3和第4,一旦事务性,一次不事务性的。

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之间的任何差别(冲洗:真,failOnError:真),保存()(有或无交易)。

有谁能解释一下save with flushwithout flush是如何工作的。

Grails doc说,刷新(可选) - 当设置为真刷新持久性上下文,立即坚持对象。但是,在我们的案例中,我们看到,它并没有发生,就像在doc中说的那样。还是我误解了它?

+0

简而言之,GORM/Hibernate尝试保存所有的INSERT/UPDATE语句,直到会话刷新。直到你手动调用'.save(flush:true)'或会话超出范围(例如最终控制器呈现/响应)。这是默认行为。以上所有内容似乎都是正常的。你期望会发生什么? –

+0

@JoshuaMoore,当我在每次保存后放入.save(flush:true)时,我希望数据库日志如下。 https://paste.ofcode.org/L8fndE865TA8htymJar82J。对于每保存(冲水:真),一个致力于 –

+1

你错过了在文档和我的答复尝试这两种关键字。您将无法以如此精确的方式使用'flush:true'来控制对数据库的提交级别。涉及到很多因素,大部分时间GORM/Hibernate将为您做出最佳选择。 –

回答

3

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