前言,用于问题验证探究,可能不太严谨,不正之处望各大大们指正
朋友遇到的一道关于事务的问题,特来验证
问题
我们都知道MySQL的默认引擎InnoDB
是支持事务的,而另外的一些引擎是不支持,比如MyISAM,当一个事务中同时包含了这两张表的数据操作时,会发生什么情况?
先放结论
首先正常运行状态下(事务内不出错)二者是可以同时存在于同一事务内,但一旦发生错误,InnoDB
表的相关数据可以正常回滚,但MyISAM
的表并不会回滚(要注意出错的位置,若为执行到MyISAM
表操作,则不会出现问题)。
验证过程
InnoDB表
# 创建表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user` varchar(32) DEFAULT NULL,
`password` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB;
# 插入数据
INSERT INTO `user` VALUES (1, 'zhangshan', '1');
INSERT INTO `user` VALUES (2, 'lishi', '2');
INSERT INTO `user` VALUES (3, 'hehe ', NULL);
INSERT INTO `user` VALUES (4, 'dd', '3');
MyISAM表
# 表结构
CREATE TABLE `user_myisam` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM ;
# 数据
INSERT INTO `user_myisam` VALUES (1, 'xingxing', 20);
INSERT INTO `user_myisam` VALUES (2, 'cc2', 6);
INSERT INTO `user_myisam` VALUES (6, 'cc2', 6);
验证一:同时使用直接报错吗?
# 正常运行
BEGIN;
INSERT into `user`(`user`,`password`) VALUES('name1','password1');
INSERT INTO `user_myisam`(`name`,`age`) VALUES('小王',18);
COMMIT;
结果:运行成功,
验证二:中间出错会回滚吗?
# 出错 -INNODB 在先且出错
BEGIN;
INSERT into `user`(`user`,`password`) VALUES('name2','password2');
INSERT into `user`(`id`,`user`,`password`) VALUES(1,'name1','password1');
INSERT INTO `user_myisam`(`name`,`age`) VALUES('小王',18);
COMMIT;
结果:事务还未执行到MyISAM
表,关于MyISAM
操作未执行,InnoDB
表正常回滚。
# 出错 -MyISAM 在前,出错在后
BEGIN;
INSERT INTO `user_myisam`(`name`,`age`) VALUES('小张',11);
INSERT into `user`(`user`,`password`) VALUES('name2','password2');
INSERT into `user`(`id`,`user`,`password`) VALUES(1,'name1','password1');
COMMIT;
结果:MyISAM
表操作不会回滚,InnoDB
表正常回滚。