初次学习Sping,我采用了编程式事务和声明式事务,executeUpdate(sql1)执行的操作都无法回滚。
数据库采用的MYSQL,是支持事务的INNODB类型
开始无法回滚怀疑是因为数据库的原因,为了排除这个问题
改用ORACLE,依然无法回滚,运行过程中没有其他异常出现(当然手动引发的运行时异常不算)。
以下是采用声明式事务的配置和代码
另外我使用编程式事务依然无法回滚
只有不使用SPRING的事务,通过同一个Connection来控制事务,回滚才能正常发生。
难道Spring的容器事务不支持我这样的操作么?
,请各位帮忙看看?感谢。
以下只是测试代码,没有考虑连接的关闭,以及性能和资源使用问题,仅仅关注事务
的原子性。
代码如下:
package com.test.dao; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; public class SpringJdbcDaoSupportTranscation4 { private DataSource dataSource = null; public SpringJdbcDaoSupportTranscation4(){ super(); } public SpringJdbcDaoSupportTranscation4(DataSource dataSource){ super(); this.dataSource = dataSource; } public void executeUpdate(String sql) throws Exception{ Statement stmt = null; Connection conn = dataSource.getConnection(); try { stmt = conn.createStatement(); stmt.executeUpdate(sql); System.out.println("execute success for:" + sql); } catch (SQLException ex) { throw new Exception("Update db failed:"+sql,ex); }finally{ stmt.close(); stmt = null; } } public void updateStudentAndCount() throws Exception{ String sql1 = "insert into STUDENT values(201201,'zhangsan')"; String sql2 = "update STUCOUNT set total=total + 1"; try{ executeUpdate(sql1); //故意引发异常 if(sql2 != null){ throw new RuntimeException("some exception"); } executeUpdate(sql2); System.out.println("transcation success!"); }catch(Exception e){ e.printStackTrace(); System.out.println("transcation failed!"); } } public static void main(String[] args) throws Exception{ ApplicationContext ctx = new ClassPathXmlApplicationContext("file:D:\\Transcation\\ApplicationCfg4.xml"); SpringJdbcDaoSupportTranscation4 springDao = (SpringJdbcDaoSupportTranscation4) ctx.getBean("springDao"); springDao.updateStudentAndCount(); } }
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="myJdbcDataSource"/> </bean> <bean id="myJdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"><value>jdbc:mysql://127.0.0.1:3306/testdb</value></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> <tx:advice id="testTxAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="updateStudentAndCount*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="daoMethod" expression="execution(* com.test.dao..*.*(..))"/> <aop:advisor pointcut-ref="daoMethod" advice-ref="testTxAdvice"/> </aop:config> <bean id="springDao" class="com.test.dao.SpringJdbcDaoSupportTranscation4"> <constructor-arg ref="myJdbcDataSource"/> </bean> </beans>