按照锁粒度进行划分
分别为行锁、页锁和表锁。
从数据库管理的角度对锁进行划分
分为:共享锁和排它锁
共享锁
共享锁也叫读锁或 S 锁,共享锁锁定的资源可以被其他用户读取,但不能修改。
给表加共享锁:
LOCK TABLE xxx READ;
当共享锁没有释放时,不能对锁住的数据进行修改。
解锁:
UNLOCK TABLE;
加行锁:
select xxx from xxx LOCK IN SHARE MODE
排他锁
排它锁也叫独占锁、写锁或 X 锁。排它锁锁定的数据只允许进行锁定操作的事务使用,其他事务无法对已锁定的数据进行查询或修改。
给表加锁:
LOCK TABLE xxx WRITE;
解锁:
UNLOCK TABLE;
加行锁
select xx from xxx for update
另外当我们对数据进行更新的时候,也就是INSERT、DELETE或者UPDATE的时候,数据库也会自动使用排它锁,防止其他事务对该数据行进行操作。
意向锁(Intent Lock),简单来说就是给更大一级别的空间示意里面是否已经上过锁。如果我们给某一行数据加上了排它锁,数据库会自动给更大一级的空间,比如数据页或数据表加上意向锁,告诉其他人这个数据页或数据表已经有人上过排它锁了,这样当其他人想要获取数据表排它锁的时候,只需要了解是否有人已经获取了这个数据表的意向排他锁即可。
如果事务想要获得数据表中某些记录的共享锁,就需要在数据表上添加意向共享锁。同理,事务想要获得数据表中某些记录的排他锁,就需要在数据表上添加意向排他锁。
从程序员的角度进行划分
可以将锁分成乐观锁和悲观锁
乐观锁(Optimistic Locking)认为对同一数据的并发操作不会总发生,属于小概率事件,不用每次都对数据上锁,也就是不采用数据库自身的锁机制,而是通过程序来实现。在程序上,我们可以采用版本号机制或者时间戳机制实现。
悲观锁(Pessimistic Locking)也是一种思想,对数据被其他事务的修改持保守态度,会通过数据库自身的锁机制来实现,从而保证数据操作的排它性。
适用场景:
- 乐观锁适合读操作多的场景,相对来说写的操作比较少。它的优点在于程序实现,不存在死锁问题,不过适用场景也会相对乐观,因为它阻止不了除了程序以外的数据库操作。
- 悲观锁适合写操作多的场景,因为写的操作具有排它性。采用悲观锁的方式,可以在数据库层面阻止其他事务对该数据的操作权限,防止读 - 写和写 - 写的冲突。
此文章为4月Day23学习笔记,内容来源于极客时间《SQL必知必会》