简体   繁体   中英

@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 ?

No, you should not use @Transactional over the controller/ controller method. @Transactional is better/correct to use in service layer or 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.

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. You can use

@Transactional(propagation=Propagation.REQUIRES_NEW)

in your service layer, and, at the same time,

@Transactional(propagation=Propagation.REQUIRED)

in your 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.

Further in your case you could make your transaction read only with @Transactional(readOnly = true) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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