2010-04-15 33 views
1

這裏是代碼的Java持久性與Hibernate書由基督教和Gavin塊,在Hibernate中手動設置flushmode時,transaction.commit()會做什麼?

 
Session session = getSessionFactory().openSession(); 
session.setFlushMode(FlushMode.MANUAL); 
// First step in the conversation 
session.beginTransaction(); 
Item item = (Item) session.get(Item.class, new Long(123)); 
session.getTransaction().commit(); 
// Second step in the conversation 
session.beginTransaction(); 
Item newItem = new Item(); 
Long newId = (Long) session.save(newItem); // Triggers INSERT! 
session.getTransaction().commit(); 
// Roll back the conversation! 
session.close();//enter code here 

我感到困惑的是,爲什麼在第一步和第二步需要被包裝成兩個獨立的交易?由於flushmode在此處設置爲手動,因此無論如何,沒有任何操作(假設我們忽略插入)將會觸發數據庫。那麼爲什麼要在這裏交易呢?

謝謝

回答

0

我想這是因爲持久性的最佳實踐原因。直到事務被提交 例如在

Long newId = (Long) session.save(newItem); 

該項目newItem不會被持久化到數據庫。而在

Item item = (Item) session.get(Item.class, new Long(123)); 

當「得到」實例的事務被提交,因爲get()將檢索持久對象。通過提交交易item從交易中分離出來並且不會被持續(直到明確更新並再次保存)。關於維基

http://en.wikipedia.org/wiki/Object_database

http://en.wikipedia.org/wiki/Persistence_%28computer_science%29

1

更多信息使用Hibernate時,必須始終有一個運行的事務。

這裏是什麼文件說約MANUAL

這種模式是隻讀交易非常有效的。

至於談話 - 他們應該跨越多種方法(read here)。所以我不認爲你的例子應該用一種方法。

正如我在文章中寫到的那樣,交易應該是「一個工作單位」。如果您發現有必要,請使用新的交易。但確保這是必要的。否則 - 不要在一個請求中進行多個事務。

+0

謝謝,但我仍然有問題(正如我在Yuval的回答中的評論中提到的那樣),我是否需要在對話中的每個步驟中進行一次交易? – wei 2010-04-16 20:49:29

+0

@薇看到更新 – Bozho 2010-04-17 07:51:15

0

正如@Bozho所說,這主要用於只讀事務。這些有用。它們允許您爲了兩個不同的目的同時使用相同版本的對象,而不會損害實際數據。在這種情況下,Hibernate緩存將爲您帶來相同的對象副本,並允許您隨意執行任何操作。

+0

謝謝,上面的代碼是從作者討論如何實現對話的章節複製的。所以你的意思是這裏的交易只對高效的只讀交易顯示出來。這實際上是我的問題,我是否需要交談中的每一個步驟? – wei 2010-04-16 20:39:00

+0

基本上,答案是否定的,但這取決於每一步的複雜性。如果您的複雜步驟必須是原子級的,則單獨的事務顯然是相關的。 – Yuval 2010-04-17 06:27:16

相關問題