关于mysql的隔离级别,在repeatable-read下的一个问题

曾经的阿飞 2010-11-21 04:49:42
第二个session

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 1 |
| 1 |
| 2 |
+------+
6 rows in set (0.00 sec)

mysql> alter table test add column name char(5) default 'a';
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> select * from test;
+------+------+
| id | name |
+------+------+
| 1 | a |
| 2 | a |
| 3 | a |
| 1 | a |
| 1 | a |
| 2 | a |
+------+------+
6 rows in set (0.00 sec)

第一个session:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 1 |
| 1 |
| 2 |
+------+
6 rows in set (0.01 sec)

mysql> select * from test;
Empty set (0.00 sec)

mysql> show global variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)


为什么在第二个session中执行alter语句add column之后,第一个session再select就什么也select不出来了,这个很方便试验,mysql版本5.1
...全文
361 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zuoxingyu 2010-11-22
  • 打赏
  • 举报
回复
2楼精辟,1楼说得也很好。

MYSQL里面的ALTER TABLE的步骤是
1:CREATE TABLE NEWTABLE(含最新的表结构);
2:INSERT INTO NEWTABLE SELECT * FROM OLDTABLE;
3: DROP TABLE OLDTABLE;
4: RENAME TABLE NEWTABLE TO OLDTABLE;

在这个过程中,SESSION1里面读取的表已经不存在了,那么也就啥都读不出来了。
iihero 2010-11-21
  • 打赏
  • 举报
回复
mysql中的特例: 记住就行了,参照:

REPEATABLE READ

这是InnoDB的默认隔离级别。带唯一搜索条件使用唯一索引的SELECT ... FOR UPDATE, SELECT ... LOCK IN SHARE MODE, UPDATE 和DELETE语句只锁定找到的索引记录,而不锁定记录前的间隙。用其它搜索条件,这些操作采用next-key锁定,用next-key锁定或者间隙锁定锁住搜索的索引范围,并且阻止其它用户的新插入。

持续读是默认模式,在其中InnoDBzai在READ COMMITTED和REPEATABLE READ隔离级别处理SELECT语句。持续读不在任何它访问的表上设置锁定,因此,其它用户可自由地在持续读在一个表上执行的同一时间修改这些表。

在持续读中,有一个与之前隔离级别重要的差别:在这个级别,在同一事务内所有持续读读取由第一次读所确定的同一快照。这个惯例意味着如果你在同一事务内发出数个无格式SELECT语句,这些SELECT语句对相互之间也是持续的,请参阅15.2.10.4节,“持续非锁定读”。



注意,持续读不在DROP TABLE和ALTER TABLE上作用。持续读不在DROP TABLE上作用,因为MySQL不能使用已经被移除的表,并且InnoDB 破坏了该表。持续读不在ALTER TABLE上作用,因为它在某事务内执行,该事务创建一个新表,并且从旧表往新表中插入行。现在,当你重新发出持续读之时,它不能在新表中看见任何行,因为它们被插入到一个在持续读读取的快照中不可见的事务里。
rucypli 2010-11-21
  • 打赏
  • 举报
回复
可重复读是指再读未提交情况下是不能更新数据的
sqlserver的可重复读是不能更新表结构的,至于你说mysql的这种情况,可能是mysql更新表结构需要重建表吧

56,782

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧