2017-07-25 78 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日誌文件中的行。