我很困惑會議和交易。我基本上都沒有看到兩者有什麼關係,而且我很困惑什麼時候使用其中一種。Grails:未刷新的會話和回滾事務之間有什麼區別?
未刷新的會話和未提交的事務之間有什麼區別?
我甚至不知道怎麼問什麼我不知道......是否有一個資源可以提供常見會話和事務情況的良好示例,以便我可以看到差異?
我很困惑會議和交易。我基本上都沒有看到兩者有什麼關係,而且我很困惑什麼時候使用其中一種。Grails:未刷新的會話和回滾事務之間有什麼區別?
未刷新的會話和未提交的事務之間有什麼區別?
我甚至不知道怎麼問什麼我不知道......是否有一個資源可以提供常見會話和事務情況的良好示例,以便我可以看到差異?
Hibernate中的事務與JDBC中的事務幾乎相同。當您從DataSource
獲得Connection
時,它默認爲autocommit = true,因此對於更改爲autocommit = false的事務。這樣,只有在明確提交時纔會在數據庫中進行更改,而不是每次執行更新。
Hibernate的Session
做了幾件事情,但在這種情況下,它的功能是作爲第一級緩存。它使用一種稱爲「事務性寫入後備」的概念來提高性能,以便對緩存中的更改進行排隊,並在必要時將其推送到數據庫。因此,例如,如果您檢索持久性實例並在複雜的多方法工作流中對其進行更改,其中每個方法可能不會發生任何更改或幾次更改,則只需要一條更新SQL語句,以便Hibernate一直等到需要將它們聚合在一起。這與您是否在交易中運行無關 - 總會發生。
在活動事務期間,會話高速緩存和活動事務聚集在一起的地方。由於Hibernate儘可能長時間地等待刷新更改,如果您不在事務中並且刷新,那麼更改將立即在數據庫中持久化。所以這是一個可以減少數據庫寫入次數的性能優化。但是,如果您正在處理事務並刷新會話,則會將更改推送到數據庫。但數據庫保留其事務隊列中的更改。因此,即使它們在數據庫中,但在您提交事務之前,它們對其他連接都不可見。
理想情況下,不會有任何顯式刷新,並且事務提交將在提交之前觸發刷新,並且這會同時最小化您需要轉到數據庫的次數,並保持未提交的更改對其他調用者不可見。但是,您可以根據需要多次沖洗。
有一件事會導致Hibernate代表您自動刷新查詢。正如我所說的,你可以對持久化實例進行很多更改(甚至刪除它們),它們只會在會話高速緩存中排隊。但是,如果您運行查詢(動態查找器,標準,HQL等),Hibernate無法知道排隊的更改是否會影響您的查詢。所以這是悲觀的,並確保一切都是一致的查詢。數據庫將爲您的查詢使用刷新但未提交的數據並返回預期結果。這就是我們建議您在自定義域類驗證程序中執行查詢時使用withNewSession
方法的原因,因此在驗證期間不會導致當前會話刷新,這可能會導致奇怪的行爲。