MySQL的隔离级别和锁的小结

1. 隔离级别

隔离级别有个叫做可重复读,而后果也有个不可重复读,描述让人有点乱,感觉作为一个“隔离级别”,应该描述能做、不能做的事,而不是一会儿状态、一会儿后果的。类似疫情,直接说多少天、只能去哪里多直观。

  • 不可重复读是因为事务中允许别人更新提交,所以连读两次结果不一样,虽然不一样,但是正确的。
  • 可重复读理论上应该是事务中不允许别人更新,保证读到的结果一样。这里我不敢确定,我只是想,如果允许别人更新,结果读的结果不变,那还不如不可重复读呢。
  • 可重复读在事务中是允许别人插入新条目的,所以读不到,但能更新到,为啥不让读到呢?先不深究了,一定是某种平衡。

1.1. 读未提交(的事务)

事务中,其他人还没提交呢(他可能回滚),就被读到了,所以导致读到了错误、过时的数据,叫脏读,不好的级别。

1.2. 读已提交

可以把这个级别叫做读已提交 + 不可重复读。事务中,读到一个数,不着急,待会儿再读,发现变了,因为过程中其他人提交了一次修改事务。这说明隔离级别还是低,我还在用呢,咋其他人就改了?在这个级别,个人觉得,读到已提交没什么问题,问题是有人在读,该不该任由其他人改,这也涉及到下文的区间锁。

1.3. 可重复读

事务中在摸鱼,一看河里没有鱼,等会儿,二看还是没鱼,管它呢,先摸一下,居然抓到了鱼,明明没鱼啊?跟幻觉似的,所以是幻读。“二看”跟“一看”相同,也就是可重复读。原来在我“等会儿”的时候,有人放进来了一条鱼,那合理吗?因为我本来就是来摸鱼的,所以也能够接受,这是MySQLInnoDB的默认级别。

1.4. 序列化

顾名思义,大家排好队一个个来,肯定慢了,倒是安全了,但不符合一般的情形。


2. 表锁、行锁

2.1. 行锁

如果UPDATEWHERE用索引做条件,那么这行就被锁住,在未提交前,其他人不能进行更新操作。如果命中了某行,就是记录锁;在可重复读级别,如果是范围搜索,不管这范围中有没有记录,这一段都无法操作(增改),形成区间锁,更低级别锁会失效。

2.2. 表锁

如果UPDATEWHERE用非索引做条件,那么会触发整个表被锁住。

你可能感兴趣的:(MySQL的隔离级别和锁的小结)