mysql事务,如何回滚数据?rollback操作是否一定会成功?
发布于 作者:苏南大叔 来源:程序如此灵动~本文讨论mysql
的数据回滚操作rollback
,人生路上有很多遗憾,多想再来重走一次。这个理念体现在mysql
里面,就是rollback
命令,给你一次数据重来的机会。但是,也不是想rollback
就一定会rollback
成功的,这也是有条件的。这些就是在本文里面,苏南大叔要阐述的主要内容。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程经验故事。本文描述mysql
数据变更的后悔药rollback
命令。测试环境:win10
,mysql@5.7.26
,mysql-front@5.3
。
rollback 与 transaction
开始语句是用于界定事务回滚的范围的,也就是说回滚到什么位置,所以不用小看这两条开始语句。事务开始transaction
的标志性语句,包括:
start transaction;
begin;
回滚rollback
是事务transaction
中的一个操作,可以单独使用。如果没执行这两条语句的话,就是当前mysql
线程开始的时候的表状态作为起始状态。这个事情就比较不可控了。本文的代码里面,begin;
的位置很关键,如果没有begin;
的合适调用,InnoDB
最终也得不到任何数据。那是因为本文的实验表的初始状态就是个空表。
事务在commit
命令之后,表示事务结束。后续的就是另外一个事务了。
rollback 与 InnoDB
只有mysql
的InnoDB
存储引擎才支持事务,所以任何类型不是InnoDB
的数据表都不支持事务,也就不会支持rollback
数据回滚。典型的类型就是MyISAM
类型的数据表,并不支持事务,无法处理rollback
命令。(但是并不会报错)
同一个数据库里面,可以有不同存储引擎的数据表。存储引擎是跟着“表”走的,并不是跟着“库”走。
参考文章:
InnoDB类型[有条件回滚]
回滚rollback
只和数据表存储类型有关,只有innodb
类型数据表支持事务,支持回滚rollback
。
定义一个InnoDB
类型的表:
DROP TABLE IF EXISTS `innodb`;
CREATE TABLE `innodb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `innodb` VALUES (1,'苏南大叔'),(2,'sunan大叔');
两次rollback
测试代码:
# 第一次
BEGIN;
delete from innodb;
rollback;
select * from innodb;
# 第二次执行的效果是有区别的
delete from innodb;
rollback;
select * from innodb;
开启autocommit
,然后测试:
set autocommit = 1;
关闭autocommit
,然后测试:
set autocommit = 0;
MyISAM类型[不支持回滚]
回滚rollback
只和数据表存储类型有关。只有MyISAM
类型数据表不支持事务,不支持回滚rollback
。
定义一个MyISAM
类型的表:
DROP TABLE IF EXISTS `myisam`;
CREATE TABLE `myisam` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `MyISAM` VALUES (1,'苏南大叔'),(2,'sunan大叔');
开启autocommit
,然后测试:
set autocommit = 1;
BEGIN;
delete from myisam;
rollback;
select * from myisam;
关闭autocommit
,然后测试:
set autocommit = 0;
BEGIN;
delete from myisam;
rollback;
select * from myisam;
rollback 与 autocommit
rollback
与autocommit
无关,只和inndbdb
有关。
- 表引擎是
InnoDB
的情况下,autocommit
无论取值什么,rollback
都能生效。 - 表引擎是
MyISAM
的情况下,autocommit
无论取值什么,rollback
都不能生效,但是也不报错。
参考文章:
rollback
在innodb
表中,在第一次执行之前,确实和autocommit
无关。但是,如果是rollback
正常回滚之后,却和autocommit
有关了。因为当autocommit=1
的情况下,rollback
后,会有个自动隐藏的commit
操作。后续的rollback
就可能达不到预期了。
rollback 生效条件
存储引擎 | autocommit | rollback | 第二次rollback |
---|---|---|---|
InnoDB | On | 恢复到begin | 最多恢复到上一次rollback |
InnoDB | Off | 恢复到begin | 恢复到begin |
MyISAM | On | 不生效 | 不生效 |
MyISAM | Off | 不生效 | 不生效 |
rollback
只和transaction
有关,同时,只有innodb
支持transaction
。结论是:只有在inndb
类型的数据表里面,才可能被rollback
。
绝对不能rollback的情况
truncate
以及alter
这种改了表属性的语句,是不会被回滚的。无论如何都无法回滚。比如:
truncate table test;
或者:
alter table test add description varchar(50);
truncate
会修改AUTO_INCREMENT
属性。
结语
人生没有回头路,珍惜当下。更多苏南大叔的mysql
经验文章,请参考:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。