AnilHoney
AnilHoney

Reputation: 249

spring transaction not working?

Hi i am try to develop spring and hibernate app with transactions , i am using spring 4.x and hibernate 4.x , here is my code snippet

applicationContext.xml

<tx:annotation-driven />
     <context:annotation-config />

     <context:component-scan base-package="com.xyx.service" />
     <context:component-scan base-package="com.xyz.dao" />


    <import resource="conf/spring/persistence.xml" />

servlet-context.xml

<context:component-scan base-package="com.xyx.webservice.components" />
     <mvc:annotation-driven />
 <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </bean>  

    <!--      Configure to plugin JSON as request and response in method handler -->
  <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonMessageConverter"/>
            </list>
        </property>
    </bean> 

persistance.xml

<bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/xyx" />
            <property name="username" value="root" />
            <property name="password" value="root" />
      </bean>

    <bean id="sessionFactory"           class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="packagesToScan" value="com.xyz.model" />       
        <property name="hibernateProperties">
            <props>

                  <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                  <prop key="hibernate.show_sql">true</prop>           
                  <prop key="hibernate.cache.use_second_level_cache">false</prop>    
            </props>
        </property>

    </bean>

    <bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager"   p:sessionFactory-ref= "sessionFactory" > 
   </bean>



    </beans>

and finnaly meservice look like this

@Transactional(propagation=Propagation.REQUIRED,rollbackFor=RuntimeException.class)
    public Object loadCategories(UserContactsInputVO inputVo) {

        User user= getUserObject(inputVo);


        userDAO.saveOrUpdateForTrancasction(user);
        System.out.println(user.getUserId());

        //getAudioFilesBasedOnCategories();
        try{
            return getAudioFilesBasedOnCategories();
        }catch (RuntimeException e) {
            e.printStackTrace();
        }
        return new CategoryResponseVo();
    }

and

@Transactional(propagation=Propagation.REQUIRED)
    public CategoryResponseVo  getAudioFilesBasedOnCategories()
    {

        try{
            if(true)
        throw new RuntimeException();

        }finally{

        }
        return vo;

    }

here runtime exception occurs but db records are not rolled backed.

Upvotes: 1

Views: 2827

Answers (1)

Shailendra
Shailendra

Reputation: 9102

The reason the transaction is not getting rolled back is beacause the RuntimeException is not getting propagated to the actual Spring proxy which manages the transaction rollback code. And the reason it is not being propagated is that you have caught it and have not rethrown.

try{
            return getAudioFilesBasedOnCategories();
        }catch (RuntimeException e) {
            e.printStackTrace(); //**THIS IS WRONG**
        }

Instead do this

 try{
                return getAudioFilesBasedOnCategories();
            }catch (RuntimeException e) {
                //log the error
                  throw e; // throw back
            }

Also you probably do not need to give rollbackFor attribute as by default on RuntimeException, the transaction is rolled back.

Upvotes: 3

Related Questions