一、介绍:
1、锁的本质
业务场景中存在共享资源,多个进程或线程需要竞争获取并处理共享资源,为了保证公平、可靠、结果正确等业务逻辑,要把并发执行的问题变为串行,串行时引入第三方锁当成谁有权限来操作共享资源的判断依据。因为数据库是多用户共享资源的,在并发环境下会破坏数据库的一致性,所以需要锁来控制它们。数据库锁机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。
2、mysql术语
(1)DDL
data manipulation language, 它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对 数据库里的数据
进行操作的语言;
(2)DML
data definition language, DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在 定义或改变表(TABLE)的结构
,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用;
(3)DCL
Data Control Language,是数据库控制功能。是用来设置或更改数据库用户或角色权限 的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行DCL
二、按操作的颗粒分类
MySQL 数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。
存储引擎 | 表级锁 | 行级锁 | 页面锁 |
---|---|---|---|
MyISAM | √ | × | × |
InnoDB | √ | √ | × |
MEMORY | √ | × | × |
BDB | √ | × | √ |
详见MySQL原理(三)锁定机制(2)表锁行锁与页锁-CSDN博客
三、按操作的类型分类
锁类型按照 操作类型划分 有「读锁(S锁),写锁(X锁)」,其实它们与共享锁,排他锁是一个意思,只是不同叫法而已。
1、共享锁(读锁/S锁)
共享锁(Shared Lock)又称为读锁,简称S锁,是一种行级锁。
共享锁
就是多个事务对于同一数据共享一把锁,都能访问到数据,但是只能读不能修改。
# 加锁方式
select ... from ... lock in share mode;
# 事务提交或回滚释放:
commit;
rollback;
2、排他锁(写锁/X锁)
排他锁(EXclusive Lock)又称为写锁,简称X锁,是一种行锁也可以是表锁。
排他锁
就是不能与其他锁并存,即当前写操作没有完成前,会阻断其他写锁和读锁。
注意:其他事务不加锁的读是不会被阻塞的,阻塞的是加锁的读
# 加锁方式:
# innodb引擎默认会在update,delete语句加上 for update
SELECT * FROM student FOR UPDATE; # 排他锁
INSERT INTO student values ... # 排他锁
DELETE FROM student WHERE ... # 排他锁
UPDATE student SET ... # 排他锁
# 事务提交或回滚释放:
commit;
rollback;
共享锁和排他锁的互斥关系:共享锁与共享锁之前兼容,排他锁不能与其他锁并存。意向锁之间是互相兼容的,意向锁与普通的表级排他锁/表级共享锁互斥(意向锁不会与行级的共享锁/排他锁互斥)。
3、意向锁(表锁)
意向锁(Intention Lock)
简称 I锁
,是表级锁的一种,它是由数据库引擎自行维护的,用户自己无需也无法操作意向锁。
意向锁
能够将 检查行锁
的时间复杂度由 O(n) 变成 O(1),其加锁的具体做法就是,当一个事务想要获取表中某一行的(共享/排他)锁的时候,它会自动尝试给当前表的加上意向(共享/排他)锁,用于防止全表扫描的一种锁。
(1)意向共享锁(IS锁-表级锁)
意向共享锁(Intention Shared Lock) 简称IS锁,事务想要给某一个数据行加行级共享锁(S锁)之前必须先获取该表的IS锁(表级锁)
(2)意向排他锁(IX锁-表级锁)
意向排他锁(Intention EXclusive Lock) 简称IX锁,事务想要给某一个数据行加行级排他锁(X锁)之前必须先获取该表的IX锁(表级锁)
4、意向锁的兼容互斥性
意向锁之间的兼容互斥性:意向锁之间是互相兼容的。
意向锁与其他锁兼容互斥性:意向锁与普通的排他锁/共享锁互斥(这的排他锁(X锁)共享锁(S锁)指的都是表锁,意向锁不会与行级的共享锁/排他锁互斥。上面表锁部分讲到的 显式加锁 加的就是排他锁/共享锁)。
四、按操作的性能分类
从操作的性能可分为乐观锁和悲观锁。乐观锁/悲观锁其实都是概念上的,只是在并发下防止数据被修改的一种加锁形式。
不同点 | 乐观锁 | 悲观锁 |
---|---|---|
实现方式 | 乐观锁需要自己实现,且外部系统不受控制,没有加锁和解锁操作,可以提高吞吐量。 | 每次请求都需要加锁、释放锁,这个过程会降低系统性能。单可以保证数据的独占性和正确性。 |
实现方式 | 有version方式(常用)和CAS算法两种实现方式。 | 依靠数据库提供的锁机制实现。 |
应用场景 | 读多写少 。 | 写多读少。 |