简体   繁体   English

@交易与否

[英]@Transactional or Not

I have code. 我有代码。

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


}

And Controler 和控制器

@Autowired
ArticlesDao dao;

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

My question is whether Handler getHome() should be annotated @Transactional ? 我的问题是是否应将Handler getHome()注释为@Transactional

No, you should not use @Transactional over the controller/ controller method. 不,您不应在控制器/控制器方法上使用@Transactional。 @Transactional is better/correct to use in service layer or DAO. @Transactional更好/正确用于服务层或DAO。

Normally I use @Transactional in the service layer and not in the DAO, since I want the transaction to hold an operation of business value and not an elementary operation. 通常我在服务层而不是DAO中使用@Transactional,因为我希望事务处理保留业务价值操作,而不是基本操作。

In controllers, as in your example there is no real code, but just delegation to a service method, where the transaction is started, so you don't need to start another transaction in the Controller. 在控制器中,如您的示例中一样,没有真正的代码,而只是委派给服务方法(在该方法中启动事务),因此您无需在控制器中启动另一个事务。

It is a good point to start your declarative transactions on your service/bussiness layer. 最好在服务/业务层上启动声明式事务。

Anyway I think that @Transactional should be used in the service layer, and, at the same time, in the integration layer. 无论如何,我认为@Transactional应该在服务层中使用,同时在集成层中使用。 You can use 您可以使用

@Transactional(propagation=Propagation.REQUIRES_NEW)

in your service layer, and, at the same time, 在您的服务层中,同时

@Transactional(propagation=Propagation.REQUIRED)

in your DAO. 在您的DAO中。 Your integration layer will be more independent, and more easily testeable in a transactional enviroment. 您的集成层将更加独立,并且在事务环境中更易于测试。

Only the service layer and not the DAO should know the transaction behaviour because this is part of the business logic. 只有服务层而不是DAO才应该知道事务行为,因为这是业务逻辑的一部分。

Further in your case you could make your transaction read only with @Transactional(readOnly = true) . 此外,您可以使用@Transactional(readOnly = true)将事务@Transactional(readOnly = true)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM