title: Spring MVC JDBC DataSourceTransactionManager: Data committed even after readonly=true
body: <p>I am currently developing a Spring MVC application.I have configured a JDBC TransactionManager and I am doing declarative transaction management using AOP XML.However, even if I configure the method to run on a read-only=true, it still commits the transaction.</p>
  
  <p>Database : Oracle 10g</p>
  
  <p><strong>My database-config.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schem...ring-beans.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop.xsd"&gt;
  
  
      &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"&gt;
          &lt;property name="driverClassName" value="${driver}" /&gt;
          &lt;property name="url" value="${url}" /&gt;
          &lt;property name="username" value="${username}" /&gt;
          &lt;property name="password" value="${password}" /&gt;
          &lt;property name="defaultAutoCommit" value="false" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="mapperLocations" value="classpath:com/mybatis/mappers/*.xml" /&gt;
      &lt;/bean&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="*" read-only="true" rollback-for="RuntimeException"/&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 FooService interface
      --&gt;
      &lt;aop:config&gt;
          &lt;aop:pointcut id="fooServiceOperation"
              expression="execution(* com.service.EmployeeService.*(..))" /&gt;
          &lt;aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" /&gt;
      &lt;/aop:config&gt;
  
  
  &lt;/beans&gt;
  </code></pre>
  
  <p><strong>My controller</strong></p>
  
  <pre><code>package com.service;
  
  import java.util.List;
  
  import com.mybatis.dao.EmployeeMapperInterface;
  import com.spring.model.Employee;
  
  public class EmployeeService implements EmployeeBaseService{
  
      EmployeeMapperInterface employeeMapper;
  
      public EmployeeMapperInterface getEmployeeMapper() {
          return employeeMapper;
      }
  
      public void setEmployeeMapper(EmployeeMapperInterface employeeMapper) {
          this.employeeMapper = employeeMapper;
      }
  
      @Override
      public Employee getEmployeeById(long empId){
          //retrieve from database
          List empList = employeeMapper.getEmployeeWithId(empId);
          if(empList != null &amp;&amp; empList.size()&gt;0){
              return (Employee) empList.get(0);   
          }
          return null;
  
      }
  
  
  
  
        @Override
      public long saveEmployee(Employee employee){
          long empId = 0l;
          if(employee.getEmpId()==0){
              empId  = new Long( employeeMapper.insertEmployee(employee));
          }else{
               employeeMapper.updateEmployee(employee);
               empId  =  employee.getEmpId();
          }
          try {
              System.out.println("gonna sleep");
              Thread.sleep(10);
  
          } catch (InterruptedException e) {
  
              e.printStackTrace();
          }
          return empId;
      }
  </code></pre>
  
  <p>How do I prevent the auto commit?I have also noticed that even if I don't put any transaction management code, the code still commits. Note, the transaction advice is however,invoked as when I put a no-rollback-for for RuntimeException and then do a 1/0, it correctly commits the data and rolls back if I put the same as rollback-for.
  I have also tried out the query timeout by putting the thread on sleep, even that doesn't work, but I figure that timeout might be for an actual query, so thats fine.
  Thanks in advance!</p>