要想写好“增删改查”,你必须知道的MySQL InnoDB相关知识

此生再无相见时 提交于 2020-01-03 05:34:34

MySQL InnoDB

MySQL InnoDB是最常用的MySQL数据库引擎,作为一个后端程序员,必须对它有所了解。这篇博客的相关内容是参考《MySQL技术内幕 InnoDB存储引擎》第2版

锁的类型

共享锁(SLock)

共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。SQL语句:SELECT … LOCK IN SHARE MODE

排他锁(XLock)

允许事务删除或更新一行数据。排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的锁,包括共享锁和排他锁。获取排他锁的事务是可以对一行数据读取和修改。SQL语句:SELECT FOR UPDATE

读的类型

一致性非锁定读(快照读)

如果读取的行正在执行delete或update操作,这时读取操作不会因此去等待行上的锁释放,而是去读取一个快照数据。快照数据是指该行之前版本的数据,该实现是通过undo段来完成的,而undo用来在事务中回滚数据。此外,读取快照数据是不需要上锁的,因为没有事务需要对历史的数据进行修改操作。在默认配置下,即事务隔离级别为REPEATABLE READ(可重复读)时,MySQL InnoDB使用一致性非锁定读。

一致性锁定读(当前读)

对于select语句可以加锁来实现一致性的锁定读,可以加共享锁,也可以加排他锁。

事务的隔离级别

READ UNCOMMITTED

浏览访问,俗称“读未提交”。会出现“脏读”;这种隔离级别最低,一般是在理论上存在,很少用到

READ COMMITTED

游标稳定,俗称“读提交”。这种隔离级别高于读未提交;可以避免“脏读”;但会导致“不可重复读”

REPEATABLE READ

俗称“重复读”。这种隔离级别高于“读已提交”;可以实现可重复读,也可以避免“幻读”

SERIALIZABLE

隔离,俗称“串行化”。在此事务隔离级别,InnoDB存储引擎会对每个select语句后自动加上lock in share mode,因此对一致性的非锁定读不再予以支持。

事务的并发问题

脏读

指的是在不同的事务中,当前事务可以读到另外事务未提交的数据。比如:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。

不可重复读

是指在一个事务内多次读取同一数据集合,在这个事务还没有结束时,另外一个事务也访问了该同一数据集合,并做了一些DML操作。因此,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。
(ps:网上还有一种“幻读”的说法,个人认为跟“不可重复读”其实是同一类问题,只不过“幻读”是先select,发现不存在再insert,结果发现数据又存在导致insert失败)。

丢失更新

简单来说就是一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致。不过,在当前数据库的任何隔离级别下,都不会导致数据库理论上的丢失更新问题。这是因为,即使是READ UNCOMMITTED的事务隔离级别,对于行的DML操作,需要对行或其他粗粒度级别的对象加锁。不论你的事务隔离级别是什么样的,只要你开启事务修改了一行数据还没有提交,你就获得了这行数据的写锁,其他事务就不能再修改这条记录。事务隔离级别只是确认其他事务能不能读取到你修改过但未提交的数据记录而已,当你修改完成提交事务,其他事物才能获得这行记录的修改权限,才能执行修改操作。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!