Mysql默认是自动提交的,如果要开启使用事务,首先要关闭自动提交后START TRANSACTION 或者 BEGIN 来开始一个事务,使用ROLLBACK/COMMIT来结束一个事务。但即使如此,也并不是所有的操作都能被ROLLBACK,以下语句在执行后会导致回滚失效,比如DDL语句创建一个数据库,而且不止此,这样的语句包括以下这些等:
ALTER FUNCTION,ALTER PROCEDURE,ALTER TABLE,BEGIN,CREATE DATABASE,CREATE FUNCTION,CREATE INDEX,CREATE PROCEDURE,CREATE TABLE,DROP DATABASE,DROP FUNCTION,DROP INDEX,DROP PROCEDURE,DROP TABLE,LOAD MASTER DATA,LOCK TABLES,RENAME TABLE,SET AUTOCOMMIT=1,START TRANSACTION,TRUNCATE TABLE,UNLOCK TABLES,CREATE TABLE,CREATE DATABASE DROP DATABASE,TRUNCATE TABLE,ALTER FUNCTION,ALTER PROCEDURE,CREATE FUNCTION,CREATE PROCEDURE,DROP FUNCTION和DROP PROCEDURE...
这些语句(以及同义词)均隐含地结束一个事务,即在执行本语句前,它已经隐式进行了一个COMMIT。InnoDB中的CREATE TABLE语句被作为一个单一事务进行处理。所以ROLLBACK不会撤销用户在事务处理过程中操作的CREATE TABLE语句。另外上面的语句中包括START TRANSACTION,这即是说明事务不能被嵌套。事物嵌套会隐式进行COMMIT,即一个事务开始前即会把前面的事务默认进行提交。
在这个页面 https://blog.csdn.net/qingsong3333/article/details/77018567 上看到这个例子,如下图:
看图上说:是因为CREATE语句已经隐式地commit了。之后的语句都是自动提交的。我就感觉这里有问题,自己试了一下,果真是有问题,如下命令:
#执行SQL命令setautocommit=0;start transaction;create table teachers(id int AUTO_INCREMENT,tname varchar(50),PRIMARY KEY (id));INSERT INTO students(username)VALUES(‘lisi‘);rollback;#执行结果:[SQL]setautocommit=0;受影响的行:0时间:0.001s[SQL]start transaction;受影响的行:0时间:0.000s[SQL]create table teachers(id int AUTO_INCREMENT,tname varchar(50),PRIMARY KEY (id));受影响的行:0时间:0.171s[SQL]INSERT INTO students(username)VALUES(‘lisi‘);受影响的行:1时间:0.001s[SQL]rollback;受影响的行:0时间:0.126s
上面的在执行过程中,ROLLBACK虽然不能撤回create table语句,但是数据插入行是会回滚的(表students数据未增加,但自增字段会增加1)。真不知道它的结论是怎么来的,误导人啊,真捉急!!真捉急!!
总之关于START TRANSACTION 和autocommit,
1.不管autocommit 是1还是0,START TRANSACTION 后,只有当commit数据才会生效,ROLLBACK后就会回滚(不能回滚的DDL语句等除外)。
2.当autocommit 为 0 时,不管有没有START TRANSACTION。只有当commit数据才会生效,ROLLBACK后就会回滚。
3.如果autocommit 为1,并且没有START TRANSACTION。调用ROLLBACK是没有用的。即便设置了SAVEPOINT。
上面谈到了设置SAVEPOINT, savepoint正如其字面意思,保存点,在事务中可以设定保存点,回滚的时候可以自由定义回滚至某个保存点,而不用一定要回滚到事务开始的时候的数据状态,官方介绍:保存点(savepoint)是事务过程中的一个逻辑点,用于取消部分事务,当结束事务时,会自动的删除该事务中所定义的所有保存点。当执行rollback时,通过指定保存点可以回退到指定的点。如下示例一看便懂。
setautocommit =0;start transaction;INSERT INTO students(username)VALUES(‘haha‘);SAVEPOINT tempa;INSERT INTO students(username)VALUES(‘haha_2‘);ROLLBACK TO SAVEPOINT tempa;#此处使用不使用RELEASE都可以,会自动删除RELEASE SAVEPOINT tempa;COMMIT;
Mysql中的隐式COMMIT以及Savepoints的作用
原文:https://www.cnblogs.com/xiami2046/p/13180933.html