Spring AOP声明式事务管理不起作用

时间:2013-01-14 05:35:54

标签: spring transactions declarative

我正在尝试编写一个简单的应用程序来了解Transaction如何在Spring中工作(Declarative AOP Style)。我正在将一条记录插入到customer表中,然后抛出NullPointerException以查看插入的数据是否已回滚。但令我惊讶的是,它并没有回滚数据。这是代码

ApplicationContext.xml文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="

    http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    ">

<aop:aspectj-autoproxy />

<bean id="BoardingService" class="com.learning.maven.services.BoardingServiceImpl"/>

<tx:advice id="txAdvice" transaction-manager="transactionManager" >
    <tx:attributes>
        <tx:method name="getUser*" rollback-for="throwable" propagation="REQUIRES_NEW"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="boardingServiceOperation" expression="execution(* com.learning.maven.services.BoardingService.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="boardingServiceOperation"/>
</aop:config>

<bean id="transactionManager"  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="jdbc:oracle:thin:@localhost:1521:XE"/>
    <property name="username" value="system"/>
    <property name="password" value="Manager"/>
</bean>

<bean id="customerDAO" class="com.learning.maven.dao.CustomerDAOImpl">
    <property name="dataSource" ref="dataSource" />
</bean>

这就是我调用方法的方法

public static void main(String[] args) {

    context = new FileSystemXmlApplicationContext("C:\\workspace\\learning\\cxf\\SpringTransaction\\cxf.xml");
    BoardingService bean = (BoardingService) context.getBean("BoardingService");
    bean.getUser("1");

}

BoardingService类如下所示

public class BoardingServiceImpl implements BoardingService, ApplicationContextAware {

    ApplicationContext context = null;

    public String getUser(String id) {

        String response = "SUCCESS";
        try{
            System.out.println("Testing");
            CustomerDAO customerDAO = (CustomerDAO) Testing.context.getBean("customerDAO");

            Customer c = new Customer();
            c.setAge(31);
            c.setCustId(1);
            c.setName("Jagadeesh");


            customerDAO.insert(c);

            customerDAO.insert(null);
        }
        catch(Exception e){
            throw new RuntimeException();
        }

        return response;
    }

    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        this.context = arg0;

    }

和CustomerDAOImpl

private DataSource dataSource;

public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}

public void insert(Customer customer) {

    String sql = "INSERT INTO CUSTOMER (CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
    Connection conn = null;

    try {
        conn = dataSource.getConnection();
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, customer.getCustId());
        ps.setString(2, customer.getName());
        ps.setInt(3, customer.getAge());
        ps.executeUpdate();
        ps.close();

    } catch (SQLException e) {
        throw new RuntimeException(e);

    } finally {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {}
        }
    }       
}

public Customer findByCustomerId(int custId) {
    // TODO Auto-generated method stub
    return null;
}

不知道我哪里错了。任何指针都会有很大的帮助。

2 个答案:

答案 0 :(得分:0)

您已回滚"throwable"而不是"Throwable".

P.S。不确定是否应使用REQUIRES_NEW作为默认策略。

更新:来自DataSourceTransactionManager文档

  

需要应用程序代码来检索JDBC连接   DataSourceUtils.getConnection(DataSource)而不是标准   J2EE样式的DataSource.getConnection()调用。春天课如   JdbcTemplate隐式使用此策略。如果不组合使用   使用此事务管理器,DataSourceUtils查找策略   行为与本机DataSource查找完全相同;因此可以使用它   便携式。

在您的情况下,您直接打开连接,然后Oracle在关闭时提交事务(这是Oracle RDBMS的一项功能)。

答案 1 :(得分:0)

您也可以省略rollback-for属性。然后,如果发生任何RuntimeException,它将回滚。