数据库之锁模块

  

MyISAM与InnoDB关于锁方面的区别

  

MyISAM与InnoDB关于锁方面的区别:

  
      <李> MyISAM默认使用的是表级锁,不支持行级锁李   <李> InnoDB默认用的是行级锁,也支持表级锁李   <李> InnoDB支持事务,在事务中被加锁的数据行需要等事务承诺之后才会统一解锁,否则不会解锁。而MyISAM不支持事务,所以不会有这个问题   <李> MyISAM和InnoDB都支持共享锁和排他锁,读锁共享,写锁排他李   <李> InnoDB在开启事务时,若选择语句不走索引的情况会锁住整张表,也就是说InnoDB在SQL没有利用到索引的时候使用的是表级锁,而SQL用到索引的时候则是使用行级锁锁和差距,差距锁是走普通非唯一索引时用到的李   <李> InnoDB除了支持行级锁之外,还支持表级的意向锁,意向锁分为共享读锁(是)和排他写锁(IX)   
  注:

  
  

实际上在不走索引的时候,InnoDB的实现方式和MyIsam的表锁方式不同,单条索引记录上加锁,记录锁锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么InnoDB会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁(排他锁),此时想改变树型结构即索引结构的话,是会被锁住的,这个类似于表锁,但原理上和表锁是完全不同的

     

MyISAM适合的场景:

  
      <李>频繁执行全表数语句李   <李>对数据进行增删改的频率不高,而查询非常频繁的场景李   <李>没有事务场景李   
  

InnoDB适合的场景:

  
      <李>数据进行增删改查都相当频繁的系统李   <李>可靠性要求比较高,需要事务特性的系统李   
  

数据库锁的分类:

  
      <李>按锁的粒度划分,可分为表级锁,行级锁,页级锁李   <李>按锁级别划分,可分为共享锁,排他锁李   <李>按加锁方式划分,可分为自动锁,显式锁李   <李>按操作划分,可分为DML锁,DDL锁李   <李>按使用方式划分,可分为乐观锁,悲观锁;悲观锁通常需要利用数据库提供的锁机制来实现,而乐观锁通常用版本号或时间戳来实现李   
  

<强>总结:

  

MyISAM默认使用的是表级锁,不支持行级锁.InnoDB默认用的是行级锁,也支持表级锁。无论是表级锁还是行级锁,均分为共享锁和排他锁,它们的关系如下表所示(X:排他锁,年代:共享锁):
数据库之锁模块

  <人力资源/>   

事务隔离级别以及各级别下的并发访问问题以及事务隔离机制

  

事务并发访问引起的问题以及如何避免:

  

1。更新丢失:

  
  

即一个事务的更新覆盖了另一个事务的更新,由于现在主流数据库都会自动加锁来避免更新丢失的情况,所以在数据库层面通常不会发生这个问题,例如mysql所有事务隔离级别在数据库层面上均可避免更新丢失

     

下图模拟了更新丢失的过程:
数据库之锁模块

  

2。脏读(脏读):

  
  

即一个事务读到另一个事务的未提交数据,该问题在读取提交(读已提交)以上的事务隔离级别可避免

     

3。不可重复读(不可重复读):

  
  

即事务多一次读取同一数据,但事务B在事务多一次读取的过程中对该数据做了更新操作并提交,导致事务多一次读取同一数据时结果不一致,该问题在可重复读(可重复读)以上的事务隔离级别可避免,这也是MySQL的默认隔离级别

     

4。幻读(幻像读):

  
  

事务一个读取以搜索条件相匹配的若干行数据,而事务B则对事务一查询匹配的数据进行了插入或删除操作,导致事务多一次读取的结果集行数不一致,该问题在序列化(串行化)以上的事务隔离级别可避免,需要注意的是:在MySQL数据库中,可重复读事务隔离级别下也可以避免幻读

     

总结:
数据库之锁模块

  <人力资源/>   

当前读和快照读

  

表象:快照读(非阻塞读)——伪MVCC(多版本并发控制)

数据库之锁模块