spring + hibernate + mysql 事务不回滚
2012-11-20 14:52
330 查看
首先声明,这个问题涉及到的数据库是MySQL。这是个很奇怪的问题,事务怎么会不回滚呢?实际上这是个愚蠢的问题,是经验不足导致的,越是奇怪的问题解决起来就越容易。不回滚的根本原因不在Hibernate,更不是SSH框架,而在MySQL本身。
查看MySQL数据库使用的存储引擎:mysql>show variables like '%storage_engine%';结果:+----------------+--------+ |Variable_name |Value| +----------------+--------+ |storage_engine|InnoDB| +----------------+--------+ 1
row in set
查看MySQL提供什么存储引擎:mysql>show engines;结果:+------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints | +------------+---------+----------------------------------------------------------------+--------------+------+------------+ | MyISAM | YES | Default engine as of MySQL 3.23 with great performance
| NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | FEDERATED |
NO | Federated MySQL storage engine | NULL | NULL | NULL | | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | MEMORY | YES | Hash based, stored in
memory, useful for temporary tables | NO | NO | NO | +------------+---------+----------------------------------------------------------------+--------------+------+------------+ 8 rows in set
从结果上看,当前数据库的默认存储引擎是InnoDB(注意观察Support这一列的值),不过有的数据库却不是,它们默认的是MyISAM。非但如此,在Support一栏中还显示NO,就是说连InnoDB都不支持。这就是为什么不回滚的原因:InnoDB支持事务,而MyISAM不支持!其实MyISAM是MySQL默认的存储引擎,在安装MySQL时如果没有指定存储引擎,那么MySQL会默认使用MyISAM,因为它不支持事务,也许效率会比InnoDB高一些。
如果使用的是MyISAM,那么需要将其改为InnoDB,具体方法如下:1、打开“MySQL_HOME/my.ini”,找到[mysqld],在它的下面有一句话是“skip-innodb”,将其注释掉,即改为:#skip-innodb。2、在[mysqld]下加上一句“default_table_type=INNODB”(如果写成default-storage-engine=INNODB也可以,两者之间的区别我还没有研究过)3、重启MySQL服务(注意:是重启服务,不是光退出数据库就完事了!)4、再次执行mysql>
show engines;可以看见默认存储引擎已经变成InnoDB了。5、原来已经存在的表,如果想使用事务,要修改它的存储引擎,在默认是InnoDB的情况下删除重建。当不想删除的时候,执行alter table 表名 ENGINE = InnoDB;之后执行show table status from 数据库名 where name='表名';可以查看表状态,看存储引擎是否被修改了。
在使用了InnoDB引擎之后,再次运行代码,回滚成功!
查看MySQL数据库使用的存储引擎:mysql>show variables like '%storage_engine%';结果:+----------------+--------+ |Variable_name |Value| +----------------+--------+ |storage_engine|InnoDB| +----------------+--------+ 1
row in set
查看MySQL提供什么存储引擎:mysql>show engines;结果:+------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints | +------------+---------+----------------------------------------------------------------+--------------+------+------------+ | MyISAM | YES | Default engine as of MySQL 3.23 with great performance
| NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | FEDERATED |
NO | Federated MySQL storage engine | NULL | NULL | NULL | | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | MEMORY | YES | Hash based, stored in
memory, useful for temporary tables | NO | NO | NO | +------------+---------+----------------------------------------------------------------+--------------+------+------------+ 8 rows in set
从结果上看,当前数据库的默认存储引擎是InnoDB(注意观察Support这一列的值),不过有的数据库却不是,它们默认的是MyISAM。非但如此,在Support一栏中还显示NO,就是说连InnoDB都不支持。这就是为什么不回滚的原因:InnoDB支持事务,而MyISAM不支持!其实MyISAM是MySQL默认的存储引擎,在安装MySQL时如果没有指定存储引擎,那么MySQL会默认使用MyISAM,因为它不支持事务,也许效率会比InnoDB高一些。
如果使用的是MyISAM,那么需要将其改为InnoDB,具体方法如下:1、打开“MySQL_HOME/my.ini”,找到[mysqld],在它的下面有一句话是“skip-innodb”,将其注释掉,即改为:#skip-innodb。2、在[mysqld]下加上一句“default_table_type=INNODB”(如果写成default-storage-engine=INNODB也可以,两者之间的区别我还没有研究过)3、重启MySQL服务(注意:是重启服务,不是光退出数据库就完事了!)4、再次执行mysql>
show engines;可以看见默认存储引擎已经变成InnoDB了。5、原来已经存在的表,如果想使用事务,要修改它的存储引擎,在默认是InnoDB的情况下删除重建。当不想删除的时候,执行alter table 表名 ENGINE = InnoDB;之后执行show table status from 数据库名 where name='表名';可以查看表状态,看存储引擎是否被修改了。
在使用了InnoDB引擎之后,再次运行代码,回滚成功!
相关文章推荐
- Spring+hibernate+mysql事物不回滚的原因以及处理
- Spring+hibernate+mysql事物不回滚的原因以及处理
- [spring,mysql] spring使用注解式事务声明(@Transactional)无法回滚 .
- 终极办法:解决spring mvc+mysql+mybatis事务不提交不回滚的问题
- Spring+hibernate+mysql事物不回滚的原因以及处理
- MySql + Spring 声明式事务不回滚
- Spring+hibernate+mysql事物不回滚的原因以及处理
- spring整合Hibernate事务不能自动回滚
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚
- mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚
- spring中配置hibernate事务管理,出错时事物不回滚
- Spring+hibernate+mysql事物不回滚的原因以及处理
- Spring+hibernate+mysql事物不回滚的原因以及处理
- Spring+hibernate+mysql事物不回滚的原因以及处理
- Spring+hibernate+mysql事物不回滚的原因以及处理
- mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚
- springmvc+hibernate整合事务不回滚
- mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚
- Spring+hibernate+mysql事物不回滚的原因以及处理
- [spring,mysql] spring使用注解式事务声明(@Transactional)无法回滚