Most likely your UserServiceImpl is created in the servlet context by mistake - check the context:component-scan expressions to verify that only the Controller classes are included there.
See @ Service created twice for examples of component scan filters.
For example, if the transaction manager bean and <tx:annotation-driven> declared in the context of the root web application , then transaction proxies will be created only for beans in the root context of the application (from the Spring Documentation ):
The BeanPostProcessor interfaces are bound to a container. This is only if you use container hierarchies. If you define a BeanPostProcessor in one container, it will only do work on beans in that container. beans that are defined in one container are not processed by the BeanPostProcessor in another container, even if both containers are part of the same hierarchy.
It is less likely that the transactional configuration of the user service is configured to use a different transaction manager (or other default distribution), but in this case, the TransactionInterceptor call will be present in the stack trace of the DAO method.
It’s absolutely normal to have @Transactional on DAO classes in Spring, if you understand what you are doing - the idea that the repository or DAO cannot open transactions comes from the dark times when you had to create boilerplate code to open transactions, and it was difficult to manage transaction instances (and you couldn't be sure how transactions were managed). But when you use declarative configuration, everything is not so bad. Spring supports a configuration convention style in which most methods use the Propagation.REQUIRED transaction mode. Spring Propagation.REQUIRED uses the default mode when you decorate methods using @Transactional (this distribution is strictly indicated in the @Transactional annotation @Transactional ), this means that the new logical transaction is mapped to the same physical transaction, therefore decorating your Classes DAOs with @Transactional harmless.
See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html#tx-propagation for a link to distributing a transaction in Spring
In Spring Data JPA (I'm sure they know what they are doing), for example, CRUD methods on repository instances are transactional by default . This can be useful in some cases, the mechanism is the same as when Hibernate allows you to get () some arbitrary objects from Session to display without declaring an explicit transaction (of course, this does not mean that the infrastructure somehow leaves without a transaction - this is implied in in this case).