在计算机科学中, 锁是在执行多线程时用于强行限制资源访问的同步机制, 即用于在并发控制中保证对互斥要求的满足.
在 数据库的锁机制 中介绍过, 在 DBMS 中, 可以按照锁的粒度把数据库锁分为行级锁 (INNODB 引擎), 表级锁 (MYISAM 引擎) 和页级锁 (BDB 引擎).
行级锁
行级锁是 Mysql 中锁定粒度最细的一种锁, 表示只针对当前操作的行进行加锁. 行级锁能大大减少数据库操作的冲突. 其加锁粒度最小, 但加锁的开销也最大. 行级锁分为 共享锁 和 排他锁 .
特点
开销大, 加锁慢;会出现死锁;锁定粒度最小, 发生锁冲突的概率最低, 并发度也最高.
表级锁
表级锁是 MySQL 中锁定粒度最大的一种锁, 表示对当前操作的整张表加锁, 它实现简单, 资源消耗较少, 被大部分 MySQL 引擎支持. 最常使用的 MYISAM 与 INNODB 都支持表级锁定. 表级锁定分为表共享读锁 (共享锁) 与表独占写锁 (排他锁).
特点
开销小, 加锁快;不会出现死锁;锁定粒度大, 发出锁冲突的概率最高, 并发度最低.
页级锁
页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁. 表级锁速度快, 但冲突多, 行级冲突少, 但速度慢. 所以取了折衷的页级, 一次锁定相邻的一组记录. BDB 支持页级锁
特点
开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间, 并发度一般
MySQL 常用存储引擎的锁机制
MyISAM 和 MEMORY 采用表级锁 (table-level locking)
BDB 采用页面锁 (page-level locking) 或表级锁, 默认为页面锁
InnoDB 支持行级锁 (row-level locking) 和表级锁, 默认为行级锁
Innodb 中的行锁与表锁
前面提到过, 在 Innodb 引擎中既支持行锁也支持表锁, 那么什么时候会锁住整张表, 什么时候或只锁住一行呢
InnoDB 行锁是通过给索引上的索引项加锁来实现的, 这一点 MySQL 与 Oracle 不同, 后者是通过在数据块中对相应数据行加锁来实现的. InnoDB 这种行锁实现特点意味着: 只有通过索引条件检索数据, InnoDB 才使用行级锁, 否则, InnoDB 将使用表锁!
在实际应用中, 要特别注意 InnoDB 行锁的这一特性, 不然的话, 可能导致大量的锁冲突, 从而影响并发性能.
在不通过索引条件查询的时候, InnoDB 确实使用的是表锁, 而不是行锁.
由于 MySQL 的行锁是针对索引加的锁, 不是针对记录加的锁, 所以虽然是访问不同行 的记录, 但是如果是使用相同的索引键, 是会出现锁冲突的. 应用设计的时候要注意这一点.
当表有多个索引的时候, 不同的事务可以使用不同的索引锁定不同的行, 另外, 不论 是使用主键索引, 唯一索引或普通索引, InnoDB 都会使用行锁来对数据加锁.
即便在条件中使用了索引字段, 但是否使用索引来检索数据是由 MySQL 通过判断不同 执行计划的代价来决定的, 如果 MySQL 认为全表扫 效率更高, 比如对一些很小的表, 它 就不会使用索引, 这种情况下 InnoDB 将使用表锁, 而不是行锁. 因此, 在分析锁冲突时, 别忘了检查 SQL 的执行计划, 以确认是否真正使用了索引.
行级锁与死锁
MyISAM 中是不会产生死锁的, 因为 MyISAM 总是一次性获得所需的全部锁, 要么全部满足, 要么全部等待. 而在 InnoDB 中, 锁是逐步获得的, 就造成了死锁的可能.
在 MySQL 中, 行级锁并不是直接锁记录, 而是锁索引. 索引分为主键索引和非主键索引两种, 如果一条 sql 语句操作了主键索引, MySQL 就会锁定这条主键索引;如果一条语句操作了非主键索引, MySQL 会先锁定该非主键索引, 再锁定相关的主键索引. 在 UPDATE,DELETE 操作时, MySQL 不仅锁定 WHERE 条件扫描过的所有索引记录, 而且会锁定相邻的键值, 即所谓的 next-key locking.
当两个事务同时执行, 一个锁住了主键索引, 在等待其他相关索引. 另一个锁定了非主键索引, 在等待主键索引. 这样就会发生死锁.
发生死锁后, InnoDB 一般都可以检测到, 并使一个事务释放锁回退, 另一个获取锁完成事务.
有多种方法可以避免死锁, 这里只介绍常见的三种
1, 如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表, 可以大大降低死锁机会.
2, 在同一个事务中, 尽可能做到一次锁定所需要的所有资源, 减少死锁产生概率;
3, 对于非常容易产生死锁的业务部分, 可以尝试使用升级锁定颗粒度, 通过表级锁定来减少死锁产生的概率;
参考资料
20.3.4 InnoDB 行锁实现方式
来源: http://www.bubuko.com/infodetail-2464041.html