spring + hibernate + mysql 事务不回滚

首先声明,这个问题涉及到的数据库是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引擎之后,再次运行代码,回滚成功!

你可能感兴趣的:(spring + hibernate + mysql 事务不回滚)