有一段时间没写博客,刚看到mysql的提交类型的知识点,写个小demon记录下。
mysql提交分显式提交、隐式提交及自动提交。
(1) 显式提交
用COMMIT命令直接完成的提交为显式提交。其格式为:
SQL>COMMIT;
(2) 隐式提交
用SQL命令间接完成的提交为隐式提交。这些命令是:
ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,
EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
(3) 自动提交
若把AUTOCOMMIT设置为ON,则在插入、修改、删除语句执行后,
系统将自动进行提交,这就是自动提交。其格式为:
SQL>SET AUTOCOMMIT ON;
隐式提交应用举例如下:
#表结构 mysql> show create table planet_user_blacklist\G; *************************** 1. row *************************** Table: planet_user_blacklist Create Table: CREATE TABLE `planet_user_blacklist` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `uid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户id', `created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', `updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', `add_type` tinyint(1) unsigned DEFAULT '0' COMMENT '0系统添加,1手动录入', PRIMARY KEY (`id`), UNIQUE KEY `uq_uid` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户黑名单' 1 row in set (0.00 sec) #自动提交已被关闭 mysql> show variables like 'autocommit';; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | OFF | +---------------+-------+ 1 row in set (0.00 sec) ERROR: No query specified #测试开始 mysql> select * from planet_user_blacklist; +----+----------+------------+------------+------------+ | id | uid | created_at | updated_at | add_type | +----+----------+------------+------------+-----------+ | 1 | 29904034 | 1 | 2 | 0 | | 2 | 2839939 | 2 | 2 | 0 | +----+----------+------------+------------+----------+ 2 rows in set (0.00 sec) #开启事务 mysql> begin; Query OK, 0 rows affected (0.00 sec) #新增字段 mysql> alter table planet_user_blacklist add column address varchar(100) default ''; Query OK, 0 rows affected (0.08 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> update planet_user_blacklist set address = '广州市番禺区番禺广场' where id = 1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from planet_user_blacklist; +----+----------+------------+------------+----------+--------------------------------+ | id | uid | created_at | updated_at | add_type | address | +----+----------+------------+------------+----------+--------------------------------+ | 1 | 29904034 | 1 | 2 | 0 | 广州市番禺区番禺广场 | | 2 | 2839939 | 2 | 2 | 0 | | +----+----------+------------+------------+----------+--------------------------------+ 2 rows in set (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec)
#可见事物回滚新增字段仍然被保留 mysql> select * from planet_user_blacklist; +----+----------+------------+------------+----------+---------+ | id | uid | created_at | updated_at | add_type | address | +----+----------+------------+------------+----------+---------+ | 1 | 29904034 | 1 | 2 | 0 | | | 2 | 2839939 | 2 | 2 | 0 | | +----+----------+------------+------------+----------+---------+ 2 rows in set (0.00 sec) mysql>
上面demo中先后执行begin, alter table xxx,rollback。
sql解释器遇到 begin(start transaction)候会触发commit,在事务中谨慎使用DDL。
begin_1 sql_1 begin_2 sql_2 sql_3 commit_1 rollback_1 .
begin_2 被执行的时候, sql_1 已经就被提交了, 当你再去执行commit_1的时候,那么sql_2 和 sql_3 就被提交了. 这时候再去rollback,已经失效。
mysql官网文档:https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html