Spring事务不回滚的解决方法——修改Mysql数据表引擎

在学习Spring事务管理的过程中遇到了一个很是头疼的问题,不管是声明式事务还是注解式事务遇到异常都无法回滚。起初我以为是代码或者软件的问题,但是找了很久都没解决,最后终于发现是MySQL数据表引擎的问题,所以记录下来以防将来再次遇到。


首先简单的项目搭建,这里使用的是注解式事务管理。

(1)创建数据表并插入两条数据

CREATE TABLE t_account(

id INT PRIMARY KEY auto_increment,

username VARCHAR(50),

balance DOUBLE

);

INSERT INTO t_account(username,balance) VALUES('jack',1000);

INSERT INTO t_account(username,balance) VALUES('rose',1000);

(2)创建Spring的配置文件applicationContext.xml



				
	
	    
	    
	    
	    
	
	
	
	    
	
	
	    	
	
	
	    
	
	

(3)创建AccountDao接口并创建一个转账方法transfer(),然后创建实现类AccountDaoImpl,并添加事务注解

public class AccountDaoImpl implements AccountDao {

	private JdbcTemplate jdbcTemplate;
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false)
	public void transfer(String outUser, String inUser, Double money) {
		this.jdbcTemplate.update("update t_account set balance = balance +? " 
				+ "where username = ?",money,inUser);
		//模拟出现异常
		//int i = 1/0;
		this.jdbcTemplate.update("update t_account set balance = balance -? " 
				+ "where username = ?",money,outUser);
	}
}

(4)创建测试类TransactionTest,测试jack给rose转100块钱

public class TransactionTest {
	@Test
	public void Test() {
		ApplicationContext applicationContext = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao");
		accountDao.transfer("jack", "rose", 100.0);
		System.out.println("转账成功");
	}
}

首先把int i=1/0注释掉运行看t_account表的数据

把注释去掉重新运行

rose多了100块钱而jack的金额却没有少,说明事务并没有回滚,原因如下:

这是因为Mysql中的默认引擎是MyISAM,而MyISAM并不支持事务管理,所以将数据表的引擎更改为InnoDB就行了。

MyISAM和InnoDB的基本差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能

更改Mysql数据表的引擎方法:执行sql语句

ALTER TABLE t_account ENGINE=InnoDB;

 

重新运行测试类,结果没有发生改变说明事务回滚了,至此问题解决。

 

你可能感兴趣的:(Spring,Spring,事务管理,Java,事务回滚)