@Transactional与否

时间:2013-06-09 11:38:47

标签: java spring hibernate transactions

我有代码。

@Repository
public class ArticlesDao {

    @Autowired
    private SessionFactory sessionFactory;

    /**
     * @param count Specifited how many article get from DB
     * @param start Start offset. Default 0
     * @return all get article
     */

    @Transactional
    public List<Article> getLastArticles(Integer count, Integer start) {

        if (start == null) {
            start = 0;
        }

        final Session currentSession = sessionFactory.getCurrentSession();
        final Criteria criteria = currentSession.createCriteria(Article.class);

        criteria.addOrder(Order.desc("publishedDate"));

        criteria.setFirstResult(count + start);
        criteria.setMaxResults(count);

        return criteria.list();
    }


}

和Controler

@Autowired
ArticlesDao dao;

@RequestMapping(value = "/")
        public ModelAndView getHome(@RequestParam("page") int page) {
      dao.getLastArticles("STH args");
}

我的问题是处理程序getHome()是否应该注释@Transactional

4 个答案:

答案 0 :(得分:3)

不,你不应该在控制器/控制器方法上使用@Transactional。 @Transactional在服务层或DAO中使用更好/更正。

答案 1 :(得分:2)

通常我在服务层而不是在DAO中使用@Transactional,因为我希望事务保持业务价值的操作而不是基本操作。

在控制器中,如您的示例中没有真正的代码,只是委托服务方法,其中事务已启动,因此您无需在Controller中启动另一个事务。

答案 2 :(得分:0)

在服务/业务层上启动声明性事务是一个很好的观点。

无论如何,我认为应该在服务层中使用@Transactional,同时在集成层中使用@Transactional(propagation=Propagation.REQUIRES_NEW) 。你可以使用

@Transactional(propagation=Propagation.REQUIRED)

在您的服务层中,同时

{{1}}
在你的DAO中

您的集成层将更加独立,并且在交易环境中更容易测试。

答案 3 :(得分:0)

只有服务层而不是DAO应该知道事务行为,因为这是业务逻辑的一部分。

在您的情况下,您可以使用@Transactional(readOnly = true)只读取您的交易。