title: Spring Transactions: Interface v Class
body: <p>I am trying to use Spring Transactions, and failing.  When I set them up so that my web app will launch under Tomcat, calling </p>
  
  <pre><code>TransactionAspectSupport.currentTransactionStatus ().setRollbackOnly ();
  </code></pre>
  
  <p>when I need to roll back a transaction, but the previous DB changes are not rolled back, and I get the following error in my localhost.date.log file:</p>
  
  <pre><code>SEVERE: Servlet.service() for servlet model threw exception
  org.springframework.transaction.NoTransactionException: No transaction aspect-managed TransactionStatus in scope
      at org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus(TransactionAspectSupport.java:122)
      at edu.mayo.bsi.backslapper.model.dao.impl.TransactServiceDAOImpl.giveProps(TransactServiceDAOImpl.java:160)
  </code></pre>
  
  <p>I have</p>
  
  <pre><code>public interface TransactServiceDAO
  </code></pre>
  
  <p>and </p>
  
  <pre><code>public class TransactServiceDAOImpl implements TransactServiceDAO
  </code></pre>
  
  <p>in my application-context-config.xml I have</p>
  
  <pre><code>&lt;bean id = "transactService" class = "edu.mayo.bsi.backslapper.model.dao.impl.TransactServiceDAOImpl"/&gt;
  
  &lt;!-- enable the configuration of transactional behavior based on annotations --&gt;
  &lt;!-- the transactional advice (what 'happens'; see the &lt;aop:advisor/&gt; bean below) --&gt;
  &lt;tx:advice id = "txAdvice" transaction-manager = "txManager"&gt;
      &lt;!-- the transactional semantics... --&gt;
      &lt;tx:attributes&gt;
          &lt;!-- all methods starting with 'get' are read-only --&gt;
          &lt;tx:method name = "get*" read-only = "true"/&gt;
          &lt;!-- other methods use the default transaction settings (see below) --&gt;
          &lt;tx:method name = "*"/&gt;
      &lt;/tx:attributes&gt;
  &lt;/tx:advice&gt;
  
  &lt;!-- ensure that the above transactional advice runs for any execution of an operation defined by the TransactServiceDAO interface --&gt;
  &lt;aop:config&gt;
      &lt;aop:pointcut id = "transactServiceOperation" expression = "execution(* edu.mayo.bsi.backslapper.model.dao.TransactServiceDAO.*(..))"/&gt;
      &lt;aop:advisor advice-ref = "txAdvice" pointcut-ref = "transactServiceOperation"/&gt;
  &lt;/aop:config&gt;
  
  &lt;bean id = "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
      &lt;property name = "dataSource" ref = "backDataSource"/&gt;
  &lt;/bean&gt;
  
  &lt;tx:advice id = "txAdvice" transaction-manager = "txManager"&gt;
      &lt;tx:attributes&gt;
          &lt;tx:method name = "*" rollback-for = "Throwable"/&gt;
          &lt;tx:method name = "*" rollback-for = "java.sql.SQLException"/&gt;
      &lt;/tx:attributes&gt;
  &lt;/tx:advice&gt;
  </code></pre>
  
  <p>Here's an example, a routine where a (count == 0) rollback does not undo the "delete old users".</p>
  
  <p>What am I doing wrong?</p>
  
  <pre><code>public String setUsers (DataSource dataSource, User theUser, String store, AdminUser[] newUsers)
  {
      NamedParameterJdbcTemplate  namedParameterJdbcTemplate = new NamedParameterJdbcTemplate (dataSource);
      Map&lt;String, Object&gt;         params = new HashMap&lt;String, Object&gt; ();
  
      params.put ("lanID", theUser.getLanID ());
      params.put ("storeName", store);
  
      int count = namedParameterJdbcTemplate.update (kDeleteOldUsers, params);
  
      for (AdminUser curUser : newUsers)
      {
          int userID = updateUser (namedParameterJdbcTemplate, curUser.getLanID (), curUser.getFullName (), curUser.getEmail (), null);
  
          if (userID == kError)
              userID = addUser (namedParameterJdbcTemplate, curUser);
  
          params.put ("userID", Integer.valueOf (userID));
          count = namedParameterJdbcTemplate.update (kAddStoreUser, params);
          if (count == 0) // Wasn't inserted
              TransactionAspectSupport.currentTransactionStatus ().setRollbackOnly ();
  
          params.put ("backslapsToGive", Integer.valueOf (curUser.getBackslapsToGive ()));
          params.put ("monthlyBackslaps", Integer.valueOf (curUser.getMaxBackslaps ()));
          count = namedParameterJdbcTemplate.update (kUpdateUserStores, params);
          if (count == 0) // Wasn't updated
              TransactionAspectSupport.currentTransactionStatus ().setRollbackOnly ();
      }
  
      return null;
  }
  </code></pre>