2010-10-08 107 views
2

我遇到了一個我不太瞭解的問題 - 除非使用DAO的方法註釋爲@Transactional,否則底層數據庫不會更新。我的應用運行在JPA/Hibernate,Spring和Wicket上。這是爲什麼?JPA - 只有當方法是@Transactional時數據庫纔會更新

DAO:

@Repository(value = "userDao") 
public class UserDaoJpa implements UserDao { 
    @PersistenceContext 
    private EntityManager em; 

    public User findById(Long id) { 
     return em.find(User.class, id); 
    } 

    public List findAll() { 
     Query query = em.createQuery("select e from User e"); 
     return query.getResultList(); 
    } 

    public User create(User user) { 
     em.persist(user); 
     return user;   
    } 

    public User update(User user) { 
     return em.merge(user); 
    } 

    public void delete(User user) { 
     user = em.merge(user); 
     em.remove(user); 
    } 
} 

服務:

@Service(value = "userManager") 
public class UserManagerImpl implements UserManager { 
    @Autowired 
    UserDao dao; 

    public void setUserDao(UserDao dao) { 
     this.dao = dao; 
    } 

    public List getUsers() { 
     return dao.findAll(); 
    } 

    public User getUser(String userId) { 
     return dao.findById(Long.valueOf(userId)); 
    } 

    public void saveUser(User user) { 
     dao.update(user); 
    } 

    @Transactional 
    public void removeUser(User user) { 
     dao.delete(user); 
    } 
} 

萬一我離開了@Transactional註解,數據庫沒有更新。

回答

3

那是正常的: CRUD計劃中的每個數據庫操作都需要它的事務邊界。沒有這些界限,實際上沒有什麼會寫入數據庫。 一個事務是數據庫操作(插入,更新)的集合,它們都是成功的,或者整個操作都被數據庫取消。這就是爲什麼當事務開始和結束時你必須告訴Hibernate,因此hibernate可以告訴哪些操作必須重新註冊爲工作單元。沒有事務邊界,數據庫的最終提交不會發生。

希望有幫助

+0

哦,這是有道理的。所以通常是在服務層上面的層上標記的事務邊界,我將幾個服務層調用分組在一起? – 2010-10-08 13:31:45

+0

通常你會在服務層上應用邊界,但如果你喜歡,你也可以在上面的層上定義一個額外的@Transcational,而下層的事務方法將參與上層事務。檢查谷歌的事務隔離的一些例子... – fasseg 2010-10-08 13:52:27

+0

Hibernate Docs的第11章是學習這些東西的好起點。 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html – fasseg 2010-10-08 13:53:26

-1

嘗試刷新並提交。

相關問題