title: For web MVC Spring app should @Transactional go on controller or service?
body: <p>For WebApplicationContext, should I put <code>@Transactional</code> annotations in the controller or in services? The Spring docs have me a bit confused. </p>
  
  <p>Here is my web.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"&gt;
    &lt;display-name&gt;Alpha v0.02&lt;/display-name&gt;
    &lt;servlet&gt;
      &lt;servlet-name&gt;spring&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;
  
    &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;spring&lt;/servlet-name&gt;
      &lt;url-pattern&gt;*.htm&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
  
    &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;spring&lt;/servlet-name&gt;
      &lt;url-pattern&gt;*.json&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
  
    &lt;welcome-file-list&gt;
      &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
    &lt;/welcome-file-list&gt;
  &lt;/web-app&gt;
  </code></pre>
  
  <p>Here is my application-context.xml defining a spring dispatcher servlet: </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mvc="http://www.springframework.org/schema/mvc"
          xmlns:tx="http://www.springframework.org/schema/tx"
          xsi:schemaLocation="
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/beans    
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context 
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/mvc 
              http://www.springframework.org/schema/mvc/spring-mvc.xsd"&gt;
  
      &lt;context:annotation-config /&gt;
      &lt;mvc:annotation-driven /&gt;
      &lt;tx:annotation-driven /&gt;
  
      &lt;context:component-scan base-package="com.visitrend" /&gt;
  
      &lt;bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
          &lt;property name="prefix" value="/WEB-INF/jsp/"/&gt;
          &lt;property name="suffix" value=".jsp"/&gt;
      &lt;/bean&gt;
  
       &lt;bean id="dataSource"  class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"&gt;
          &lt;property name="driverClass" value="org.postgresql.Driver" /&gt;
          &lt;property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/postgres" /&gt;
          &lt;property name="user" value="someuser" /&gt;
          &lt;property name="password" value="somepasswd" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="configLocation" value="classpath:test.hibernate.cfg.xml" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt;
        &lt;property name="dataSource" ref="dataSource" /&gt;
        &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
      &lt;/bean&gt;    
  &lt;/beans&gt;
  </code></pre>
  
  <p>Here's a service interface: </p>
  
  <pre><code>public interface LayerService {
      public void createLayer(Integer layerListID, Layer layer);
  }
  </code></pre>
  
  <p>Here's a service implementation: </p>
  
  <pre><code>@Service
  public class LayerServiceImpl implements LayerService {
  
      @Autowired
      public LayerDAO layerDAO;
  
      @Transactional
      @Override
      public void createLayer(Integer layerListID, Layer layer) {
          layerDAO.createLayer(layerListID, layer);
      }
  }
  </code></pre>
  
  <p>And here's my controller: </p>
  
  <pre><code>@Controller
  public class MainController {
  
      @Autowired
      private LayerService layerService;
  
      @RequestMapping(value = "/addLayer.json", method = RequestMethod.POST)
      public @ResponseBody
      LayerListSetGroup addLayer(@RequestBody JSONLayerFactory request) {
          layerService.createLayer(request.getListId(), request.buildLayer());
          return layerService.readLayerListSetGroup(llsgID);
      }
  }
  </code></pre>
  
  <p>The Spring documentation has me a bit confused. It seems to indicate that using a WebApplicationContext means only controllers will be investigated for @Transactional annotations and not services. Meanwhile I see tons of recommendations to make services transactional and not controllers. I'm thinking that using  <code>&lt;context:component-scan base-package="com..." /&gt;</code> in our spring-servlet.xml above so that it includes the services packages means the services are part of the context, and therefore will be "investigated" for transactional annotations. Is this accurate?</p>
  
  <p>Here's the Spring documentation blurb that got me confused: </p>
  
  <blockquote>
    <p>@EnableTransactionManagement and  only looks
    for @Transactional on beans in the same application context they are
    defined in. This means that, if you put annotation driven
    configuration in a WebApplicationContext for a DispatcherServlet, it
    only checks for @Transactional beans in your controllers, and not your
    services.</p>
  </blockquote>
  
  <p>Further, is there any performance implications or "badness" if I define a controller method as transactional, and it calls a transactional method in a another class? My hunch is no, based on the documentation, but would love validation on that.</p>