mysql诡异的改不掉情况
2019年4月10日
没有评论
今天在看丁奇老师的《MySQL实战45讲》时看到一个有趣的思考题,其实蛮考验对mysql知识的理解的。
问题是如下图这种情况:
begin;
select * from t; -- q1
update t set c=0 where c=id; --q2
select * from t; --q3
很有意思的是update前后数据是一致的,什么情况下会发生这种想象哪?
其实这道思考题主要考察了对mysql在RR级别下的可重复读和当前读。先来说一下答案,什么情况下会发生这种情况哪?另外1个事务对这4条sql语句做了修改,比如”update t set c = c+1″这种情况。当然update语句应该是发生在q1时刻之后的,不然select的结果就会是我们update之后的结果了啊。
为什么会出现这种情况哪?
这里主要考对mysql可重复读和当前读的理解。在事务中的q1阶段,select以后就创建了对t表的一致性视图,后面所有的操作都会是从这一时刻的一致性视图来读的。接下来其他事务修改了记录,可能表数据就如下了:
mysql> select * from t;
+----+------+
| id | c |
+----+------+
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
| 4 | 5 |
+----+------+
这里有一点要强调的是update语句属于当前读,而会更新当前的一致性视图(主要体现在将当前一致性视图相关的 up_limit_id修改为当前row的trx_id),不然如果其他事务有更新提交,就会被漏掉或者说覆盖了啊。因”update t set c=0 where id=c”没有有效的更新记录,如上图中“0 rows affected”,当前一致性视图也不会更新。因此下面的select语句又从一致性视图中读取到了相同的内容!
近期评论