同一会话
若执行DML后未提交,再执行DDL,DML会自动被提交
创建测试表:
drop table if exists test;
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`dt` date DEFAULT NULL,
`dt1` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
);
begin;
insert into test(name,dt,dt1) select 'test',now(),now();
select * from test;
rollback;
select * from test;
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test(name,dt,dt1) select 'test',now(),now();
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 1 | test | 2021-09-06 | 2021-09-06 21:53:06 |
+----+------+------------+---------------------+
1 row in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
Empty set (0.00 sec)
可以看到没有DDL时,可rollback;
DML后执行DDL,添加字段,会提交事务
begin;
insert into test(name,dt,dt1) select 'test',now(),now();
select * from test;
alter table test add column dt datetime;
rollback;
select * from test;
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test(name,dt,dt1) select 'test',now(),now();
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 21:55:36 |
+----+------+------------+---------------------+
1 row in set (0.01 sec)
mysql> alter table test add column dt datetime; --即使DDL失败了,前面的DML依旧提交了
rollback;
select * from test;
ERROR 1060 (42S21): Duplicate column name 'dt'
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 21:55:36 |
+----+------+------------+---------------------+
1 row in set (0.00 sec)
DML后执行DDL,创建索引,会提交事务
begin;
insert into test(name,dt,dt1) select 'test',now(),now();
select * from test;
alter table test add index idx_dt(dt);
rollback;
select * from test;
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test(name,dt,dt1) select 'test',now(),now();
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 21:55:36 |
| 3 | test | 2021-09-06 | 2021-09-06 21:57:00 |
| 4 | test | 2021-09-06 | 2021-09-06 21:59:04 |
+----+------+------------+---------------------+
3 rows in set (0.00 sec)
mysql> alter table test add index idx_dt(dt);
rollback;
Query OK, 0 rows affected, 1 warning (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 21:55:36 |
| 3 | test | 2021-09-06 | 2021-09-06 21:57:00 |
| 4 | test | 2021-09-06 | 2021-09-06 21:59:04 |
+----+------+------------+---------------------+
3 rows in set (0.00 sec)
分析表,会提交DML事务
begin;
insert into test(name,dt,dt1) select 'test',now(),now();
select * from test;
analyze table test;
rollback;
select * from test;
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test(name,dt,dt1) select 'test',now(),now();
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 21:55:36 |
| 3 | test | 2021-09-06 | 2021-09-06 21:57:00 |
| 4 | test | 2021-09-06 | 2021-09-06 21:59:04 |
| 5 | test | 2021-09-06 | 2021-09-06 22:00:42 |
+----+------+------------+---------------------+
4 rows in set (0.00 sec)
mysql> analyze table test;
rollback;
+----------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------+---------+----------+----------+
| xhy.test | analyze | status | OK |
+----------+---------+----------+----------+
1 row in set (0.01 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 21:55:36 |
| 3 | test | 2021-09-06 | 2021-09-06 21:57:00 |
| 4 | test | 2021-09-06 | 2021-09-06 21:59:04 |
| 5 | test | 2021-09-06 | 2021-09-06 22:00:42 |
+----+------+------------+---------------------+
4 rows in set (0.00 sec)
不同会话
创建测试表:
drop table if exists test;
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`dt` date DEFAULT NULL,
`dt1` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
);
会话一:
begin;
insert into test(name,dt,dt1) select 'test',now(),now();
select * from test;
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 1 | test | 2021-09-06 | 2021-09-06 22:02:53 |
+----+------+------------+---------------------+
1 row in set (0.00 sec)
会话一不提交
会话二:执行创建索引操作
alter table test add index idx_dt(dt);
mysql> alter table test add index idx_dt(dt);
卡住。。。
会话三:可以看到会话二在等元数据锁
mysql> show processlist;
+----+------+-----------+------+---------+------+---------------------------------+---------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+---------------------------------+---------------------------------------+
| 7 | root | localhost | xhy | Sleep | 95 | | NULL |
| 10 | root | localhost | xhy | Query | 41 | Waiting for table metadata lock | alter table test add index idx_dt(dt) |
| 12 | root | localhost | NULL | Query | 0 | starting | show processlist |
+----+------+-----------+------+---------+------+---------------------------------+---------------------------------------+
3 rows in set (0.00 sec)
会话一:
begin;
insert into test(name,dt,dt1) select 'test',now(),now();
select * from test;
mysql> select * from test;
+----+------+------------+---------------------+
| id | name | dt | dt1 |
+----+------+------------+---------------------+
| 2 | test | 2021-09-06 | 2021-09-06 22:07:14 |
+----+------+------------+---------------------+
1 row in set (0.00 sec)
不提交
会话二:执行analyze可正常执行
mysql> analyze table test;
+----------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------+---------+----------+----------+
| xhy.test | analyze | status | OK |
+----------+---------+----------+----------+
1 row in set (0.00 sec)
会话一:回滚,可以看到回滚成功
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from test;
Empty set (0.00 sec)
总结:
同一会话中若先执行DML,跟着执行DDL,DML 会自动被提交;
在不同会话中,若有未提交的事务,则其他会话执行DDL会被阻塞,需等待元数据锁。
analyze table 在同一会话中执行会提交前面的事务,在不同会话中无需等待元数据锁,可执行但也不会提交其他会话的事务。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




