0

我有代码。

@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();
    }


}

和控制器

@Autowired
ArticlesDao dao;

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

我的问题是是否getHome()应该注释Handler @Transactional

4

4 回答 4

3

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

于 2013-06-09T11:41:22.007 回答
2

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

在控制器中,就像在您的示例中一样,没有真正的代码,而只是委托给启动事务的服务方法,因此您不需要在控制器中启动另一个事务。

于 2013-06-09T12:21:15.940 回答
0

在您的服务/业务层上开始您的声明性事务是一个好点。

无论如何,我认为@Transactional应该在服务层中使用它,同时在集成层中使用。您可以使用

@Transactional(propagation=Propagation.REQUIRES_NEW)

在您的服务层中,同时,

@Transactional(propagation=Propagation.REQUIRED)

在你的 DAO 中。您的集成层将更加独立,并且在事务环境中更易于测试。

于 2013-06-09T17:14:54.487 回答
0

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

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

于 2013-06-09T18:31:45.200 回答