本文参考文章
MySQL锁的分类
锁类型 | 概念 | 优点 | 缺点 | 特点总结 | 分类 | 引擎支持 |
---|---|---|---|---|---|---|
行级锁(row-level locking) | 锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁 | 减少数据库操作的冲突 | 加锁开销大 | 开销大,加锁慢;易出现死锁;锁定粒度最低,发生锁冲突概览最小,并发度最高 | 共享锁、排他锁 | InnoDB |
表级锁(table-level locking) | 锁定粒度最大的一种锁,表示对当前操作的整张表加锁 | 实现简单,资源消耗较少,被大部分MySQL引擎支持 | 易发生锁冲突 | 开销小,加锁快;不会出现死锁;锁定粒度大,易发生锁冲突,并发率低 | 表共享读锁(共享锁);表独占写锁(排他锁) | MYISAM,InnoDB ,BDB |
页级锁(page-level locking) | 锁定粒度介于行级锁和表级锁之间,一次锁定相邻的一组记录 | - | - | 开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于行级和表级,并发度一般 | - | BDB |
引擎支持
MySQL默认引擎:5.1版本之前是MyISAM,之后是InnoDB
- MyISAM和MEMORY采用表级锁
- BDB采用页面锁或表级锁,默认为页面锁
- InnoDB支持行级锁和表级锁,默认为行级锁
InnoDB
- InnoDB行锁是通过给索引上的索引项加锁来实现
- 不同于MySQL,Oracle是通过在数据块中对相应数据行加锁来实现的
- 即 只有通过索引条件检索数据,InnoDB才使用行级锁,否则使用表级锁
行级锁与死锁
引擎
- MyISAM引擎不支持事务,它会一次性获得所需的全部锁,所以不会出现死锁,但由于每操作一次就会锁住整张表,容易导致性能低,并发不高
- InnoDB引擎支持事务,且使用行锁,锁是一步一步获得的,容易产生死锁。
行级锁并不直接锁记录,而是锁索引
避免死锁常用方法
- 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
- 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
- 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率