2015-04-20 74 views
1

我有以下簡化休眠測試代碼,看看如何回滾的作品。爲什麼回滾不會返回原始值?

Session session = MySessionFactory.getSession(); 
Transaction tx = session.beginTransaction(); 
try 
{ 
    //1. get a persistent User 
    User user = (User) session.get(User.class, user3Id); 
    System.out.println("1. original: user.username=" + user.getUsername()); 

    //2. update it 
    String newUserName = userName3 + "Updated"; 
    user.setUsername(newUserName); 
    session.saveOrUpdate(user); 
    session.flush(); 
    System.out.println("2. updated: user.username=" + user.getUsername()); 

    //3. rollback 
    tx.rollback(); 
    System.out.println("3. rollback: user.username=" + user.getUsername()); 

    //4. session close 
    session.close(); 
    System.out.println("4. session close: user.username=" + user.getUsername()); 
} 
catch (Exception e) 
{ 
    tx.rollback(); 

    throw e; 
} 
finally 
{ 
    session.close(); 
} 

它的作用是這樣的:

  1. 從數據庫中獲得一個持久化對象;

  2. 更新其名稱字段;

  3. 回退事務;

對於每個步驟,我打印出用戶名字段的值。我期望用戶名在回滾後,如果用戶名從步驟1。但打印出來的不是:2,3,4的所有打印輸出都是相同的,即更新後的名稱字符串。

所以回滾只是回滾數據庫但不是持久對象

什麼額外的工作我必須做的是讓持久化對象回滾到它的原始狀態,第1步的狀態?

+0

是的,它只回滾數據庫。我不會嘗試繼續使用這個Hibernate會話及其關聯的對象。你不能重新獲得實體嗎? – Thilo

+0

這是一個志願回滾。如果是由於例外,有一個新的會議是有道理的。因此,我們將回滾視爲hibernate訪問異常? – 5YrsLaterDBA

+1

對於我來說,交易工作意味着要麼完成它,要麼把它全部扔掉。無論是因爲例外還是由於「業務邏輯」都必須回滾。簡單的原則,防止事情變得混亂。 – Thilo

回答

1

刷新會話強制Hibernate將會話的內存中狀態與數據庫同步。您可以通過其他方式來提交更改,而無需運行commit()方法。

爲了讓持久化對象回滾到初始狀態,步驟1的狀態需要做什麼額外的工作?

在回滾之前刪除session.flush()。

+0

我刪除了session.flush(),打印結果完全一樣。 ?? – 5YrsLaterDBA

+1

回滾後嘗試'session.refresh(user)'從數據庫刷新其狀態。比你會看到變化。 –