Overriding transactional Annotation Spring + hiber

2019-09-10 05:03发布

问题:

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);

        }
    }

回答1:

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>