1

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.

AnilHoney
  • 259
  • 8
  • 20

1 Answers1

3

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.

Shailendra
  • 8,874
  • 2
  • 28
  • 37
  • `@Transactional(propagation=Propagation.REQUIRED) public CategoryResponseVo getAudioFilesBasedOnCategories() ` what is the need of @ transaction for above method? ... as of my knowledge it continues current transaction if any exception occurs it have acknowledge current transaction – AnilHoney Apr 14 '14 at 14:06
  • This has nothing to do with transaction behaviour in case of exception. It simply tells the Transaction manager that the invocation of this method requires a running transaction. If there is already a transaction in progress then this method invocation simply is called in the same transaction, else a new transaction is started. This is typically done to guarantee that the invocation of this method runs under transaction even when called without a service layer. Take a look at http://stackoverflow.com/questions/10740021/transactionalpropagation-propagation-required – Shailendra Apr 14 '14 at 15:44