1

I have this DAO:

@Transactional("transactionManager")
public class DAO{
     public void save(String a){...}
}

I have this class:

public class test{
...
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void save(){
        DAO.save("a");
        DAO.save("b");
       }
    }

I want the "save" method to rollback when it throws an exception, but it doesn't seem to work when an exception occurs it does not rollback, what is the proper approach for this? All the other methods in the DAO are transactional. Is there a way I can override the transactional settings of the override?

EDIT: I have updated to be, and it is still not working when throwing exception:

public class test{
...

    public void save(){
        Service.test(a,b);
       }
    }

    public class Service{
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
        public void testSave(object a, object b){
            dao.updateEntry(a);
            dao.updateEntry(b);

        }
    }
Amit Bhati
  • 5,569
  • 1
  • 24
  • 45
mel3kings
  • 8,857
  • 3
  • 60
  • 68
  • 2
    I think the service methods should be transactional not the dao methods. – Jens Aug 25 '15 at 06:49
  • @Jens should i move all the annotation to the service layer? cause i got alot of methods in daos that does not need transaction handling thats why i had annotated the dao. – mel3kings Aug 25 '15 at 06:53
  • in most cases the transaction is on service layer methods, because all dao access in the method belongs to a transaction. So thats why the annotation should be on service layer methods. – Jens Aug 25 '15 at 06:57

1 Answers1

4

Remove the Transactional annotation from the Dao layer and place a Transactional annotation in your service layer. Take a look at my code:-

@Transactional
@Service
public class Service {

    @Autowired
    private Dao1 dao1;

    @Autowired
    private Dao2 dao2;

    public Dao1 getDao1() {
        return dao1;
    }

    public void setDao1(Dao1 dao1) {
        this.dao1 = dao1;
    }

    public Dao2 getDao2() {
        return dao2;
    }

    public void setDao2(Dao2 dao2) {
        this.dao2 = dao2;
    }

    public void insertData(){
        dao1.insert1();
        dao2.insert2();
    }

In above code, if dao2.insert2() fails then dao1.insert1() will rollback.

In case when you have multiple methods in service class with different transaction properties :
You can define the @Transactional annotation on your public methods with below rule:-

When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings.

Link1: Transactional annotation on whole class + excluding a single method

Transaction support configuration setup:-

1) spring-config.xml

<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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="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/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

      <context:component-scan base-package="com.concept" />
     <tx:annotation-driven transaction-manager="txManager"/>

      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
      </bean>

     <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="" />
        <property name="username" value="" />
        <property name="password" value="" />
    </bean> 
</beans>
Community
  • 1
  • 1
Amit Bhati
  • 5,569
  • 1
  • 24
  • 45
  • If i have multiple methods with different transactional properties? – mel3kings Aug 25 '15 at 07:13
  • You can define the @Transactional annotation at the method level with appropriate propagation attribute. – Amit Bhati Aug 25 '15 at 07:14
  • Check my edit in your question..edit section and tell me if it doesn't work. – Amit Bhati Aug 25 '15 at 08:01
  • saw your edit you trying to do rollback on the testSave, I want to do rollback when there is an error in the save method – mel3kings Aug 25 '15 at 08:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/87868/discussion-between-amit-bhati-and-mel3kings). – Amit Bhati Aug 25 '15 at 08:51
  • Check your transaction support setup, I feel you are missing something there because your scenario perfectly worked for me, with same annotations. – Amit Bhati Aug 25 '15 at 09:04