我正在尝试编写一个简单的应用程序来了解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;
}
不知道我哪里错了。任何指针都会有很大的帮助。
答案 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,它将回滚。