「MySQL高级篇」MySQL锁机制 && 事务( 三 )


InnoDB 行锁行锁介绍行锁特点 :偏向InnoDB 存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高 。
InnoDB 与 MyISAM 的最大不同有两点:一是支持事务;二是采用了行级锁 。(两者是息息相关的)
事务事务及其ACID属性事务是由一组SQL语句组成的逻辑处理单元 。
事务具有以下4个特性,简称为事务ACID属性 。
ACID属性含义原子性(Atomicity)事务是一个原子操作单元,其对数据的修改,要么全部成功,要么全部失败 。一致性(Consistent)在事务开始和完成时,数据都必须保持一致状态 。隔离性(Isolation)数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的 “独立” 环境下运行 。持久性(Durable)事务完成之后,对于数据的修改是永久的 。并发事务处理带来的问题问题含义丢失更新(Lost Update)当两个或多个事务选择同一行,最初的事务修改的值,会被后提交的事务修改的值覆盖 。脏读(Dirty Reads)读到了另一个事务还未提交的数据不可重复读(Non-Repeatable Reads)一个事务执行同样的两次select语句,前后查询出来的结果不一致幻读(Phantom Reads)一个事务按照相同的查询条件重新读取以前查询过的数据,却发现其他事务插入了满足其查询条件的新数据 。幻读幻读:就像出现了“幻影”一般,原本查不到这个人,然后要插入的时候,突然又说这个人存在

  • 场景:注册问题吧,查询某个主键id是否存在,第一次查询不存在,即将插入新数据时【刚好另一个人插入了该主键id】,导致这边注册失败

「MySQL高级篇」MySQL锁机制 && 事务

文章插图
  1. 幻读在“当前读”下才会出现 。
  2. 幻读仅专指“新插入的行”【update的不算】
事务隔离级别为了解决上述提到的事务并发问题,数据库提供一定的事务隔离机制来解决这个问题 。数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使用事务在一定程度上“串行化” 进行,这显然与“并发” 是矛盾的 。
数据库的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏写、脏读、不可重复读、幻读这几类问题 。
隔离级别丢失更新脏读不可重复读幻读Read uncommitted×√√√Read committed××√√Repeatable read(默认)×××√Serializable(串行化)××××
备注 : √ 代表可能出现,× 代表不会出现。
  1. 读未提交:别人修改了某行数据,还未提交我们就能看到 。
  2. 读已提交:别人修改了某行数据,得等到提交后我们才能看到 。-- 解决脏读
  3. 可重复读:别人修改了某行数据,我们也不去读那一行数据,还是读我们当前事务最初的那个未被修改的值 。-- 解决不可重复读
  4. 串行化:对于同一行记录,“写”会加“写锁”,“读”会加“读锁” 。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行 。
例子
「MySQL高级篇」MySQL锁机制 && 事务

文章插图
  1. 读未提交:v1=v2=v3=2;B还未提交,A就可以看到了 。
  2. 读已提交:v1=1,v2=v3=2;等到B提交后,A才能看到 。
  3. 可重复读:v1=v2=1,v3=2;也就是说,所谓的可重复读,是说在当前事务提交之前,只会读取当前事务最初的值,而不去读取其他的事务;
  4. 串行化:v1=1,v2=1,v3=2;事务A中查询得到值1的时候,就会加了“读锁”,会阻塞其他事务对该行的写操作(上文我们已经有提及到相关的读锁和写锁,忘记了的小伙伴可以翻阅上文看看)所以在事务B执行“将1改成2”的时候,会被锁住 。直到事务A提交后,事务B才可以继续执行 。

    经验总结扩展阅读