从读写角度上来看:
- 共享锁(Share Lock):其实就是我们说的读锁。如果加上这个锁,我们可以读这个数据,其他事务可以同时加读锁,但是不能加写锁。
我们平时加读锁的语句就是,select后面加上lock in share mode
- 排他锁(Exclusive Lock):其实就是我们说的写锁。如果加上这个锁,我可以对数据进行读取或修改,其他事务不能对该数据加读锁或写锁。
我们平时加读锁的语句就是,select后面加上for update
扩展:我认为这是一种很好的思想,我们JUC并发包,就很好地借鉴了这一思想,比如说我看过CopyOnWriteList源码,它里面就是用这样地方式增加读写并发度的
从粒度层面来看:
- 表锁,就是锁住整张表,一般在不加索引或者索引失效的时候锁住整张表。一般要避免表锁,会降低并发度。
比如给姓名不加张三的人加锁,这时候索引失效,加的就是表锁
- 行锁,就是锁一行或者多行,需要注意的是加在索引上的
比如给姓名叫张三的人加锁,这是后可能锁住多个叫张三的记录,锁住一行或多行
- 间隙锁,就是锁住某个区间。锁的是区间,不单单是记录
比如给年龄在[1,10]区间的人加锁,锁的是区间。原有数据1-10无法修改,并且新的数据也不能插入1-10区间
- 临建锁,相当于是记录锁 + 间隙锁,又叫next-key lock。这个用途主要是RR级别下避免幻读,这是一个左开右闭的锁
从锁的意向来看:
这里模拟一个场景,事务A对表中的记录加了一个排他锁,然后事务B这时候需要对这个表加一个排他锁,事务B就需要扫描整张表,查看是否有其他事务对这张表中记录加了排他锁。
但是实际可能没有那么麻烦,事务A对表中加了一个排他锁,同时对表也加了一个意向排他锁。然后事务B一看这个表有意向排他锁,事务B就直接等待事务A执行完后再加表锁。
- 意向排他锁,当一个事务试图对整个表加排他锁之前,首先需要获得这个表的意向排他锁
- 意向共享锁,当一个事务试图对整张表加共享锁之前,首先需要获得这个表的意向共享锁