mysql数据库锁机制是什么

44次阅读
没有评论

共计 2908 个字符,预计需要花费 8 分钟才能阅读完成。

自动写代码机器人,免费开通

丸趣 TV 小编给大家分享一下 mysql 数据库锁机制是什么,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!

并发控制

数据库管理系统中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。

封锁,时间戳,乐观并发控制和悲观并发控制是并发控制主要采用的技术手段

当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。锁就是其中的一种机制(推荐教程:MySQL 教程)

锁的分类

按照操作划分,可分为 DML 锁,DDL 锁

按锁粒度划分,可分为表级锁,行级锁,页级锁(mysql)

按锁级别划分,可分为共享锁,排他锁

按加锁方式划分,可分为自动锁,显示锁

按使用方式划分,可分为乐观锁,悲观锁

DML 锁用于保护数据的完整性,其中包括行级锁(TX 锁),表级锁(TM 锁)。DDL 锁用于保护数据库对象的结构,如表,索引等的结构定义,其中包括排他 DDL 锁,共享 DDL 锁,可中断解析锁

行级锁

行级锁是 Mysql 中锁定力度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但是加锁的开销也最大。行级锁分为共享锁和排他锁

特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高

表级锁

表级锁是 Mysql 中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 Mysql 引擎支持。最常见使用的 MYISAM 与 INNODB 都支持表级锁定。表级锁定分为表分享读锁(共享锁)和表独占写锁(排他锁)

特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发性最低

页级锁

页级锁是 Mysql 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但是冲突多,行级冲突少,但是速度慢。页级锁折中,以此锁定相邻的一组纪录。BDB 支持页级锁

Mysql 常用存储引擎的锁机制

MyISAM 和 MEMORY 采用表级锁

BDB 采用页级锁或表级锁,默认是页级锁

InnoDB 支持行级锁和表级锁,默认为行级锁

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 一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务

避免死锁

如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会

在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率

对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁

共享锁和排他锁

行级锁是 MySQL 中锁定粒度最细的一种锁,行级锁能够大大减少数据库操作的冲突。行级锁分为共享锁和排他锁

1. 共享锁

共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改,直到已释放所有共享锁。

如果事务 T 对数据 A 加上共享锁后,那么其他事务只能对 A 再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据

如果事务 T 对数据 A 加上共享锁后,又对数据进行修改,那么其他事务将不能获取共享锁;同样的,若多个事务对同一数据获取共享锁,则任何事务不能对该数据进行修改

用法:SSELECT … LOCK IN SHARE MODE

在查询语句后面增加 LOCK IN SHARE MODE,Mysql 会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取到的是同一个版本的数据

2. 排他锁

排他锁又称写锁,如果事务 T 对数据 A 加上排他锁后,则其他事务不能再对 A 加任何类型的封锁。获取排他锁的事务既能读数据,又能修改数据

用法:SELECT … FOR UPDATE。在查询语句后面增加 FOR UPDATE,MySQL 会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞

3. 意向锁

意向锁是表级锁,其设计目的是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁:

意向共享锁(IS):表示事务准备给数据行加入共享锁,也即是说一个数据行加共享锁前必须先取得该表的 IS 锁

意向排他锁(IX):表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先去的该表的 IX 锁

意向锁是 InnoDB 自动加的,不需要用户干预

总结

对于 insert,update,delete,InnoDB 会自动给涉及到的数据加排他锁;对于一般的 Select 语句,InnoDB 不会加任何锁,事务可以通过以下语句给显式加上共享锁或排他锁

共享锁:select … LOCK IN SHARE MODE

排他锁:SELECT … FOR UPDATE

看完了这篇文章,相信你对 mysql 数据库锁机制是什么有了一定的了解,想了解更多相关知识,欢迎关注丸趣 TV 行业资讯频道,感谢各位的阅读!

向 AI 问一下细节

丸趣 TV 网 – 提供最优质的资源集合!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-18发表,共计2908字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)