一、前言
平时开发都有用到数据库,也知道里面有锁的说法,那什么是锁? 锁有哪些作用? 有哪些锁?以下以MySQL8来说
二、什么是锁
锁是用于管理对共享资源并发访问的一种机制, 且是数据库系统区别于文件系统的一个关键特性。
三、为什么需要锁
举个现实生活中的例子:商品搞活动时,商品数少但价格优惠引来了很多用户抢购,如果在某一个时刻点有大量请求扣减这个商品数(db能hold住的情况),那么这个商品就有可能导致超卖。
?为什么会这样呢,因为数据在某个时刻出现了不一致性。 所以为了保证一致性,则需要有锁的介入。
数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。同时也会影响并发量
四、有哪些锁
Latch一般称为闩锁(轻量级的锁),因为其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差。
在InnoDB引擎中,Latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。
Lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。
Lock锁根据粒度主要分为表锁、页锁和行锁。不同的存储引擎拥有的锁粒度都不同。
表锁
表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。
该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。
由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。
当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并发度大打折扣。
表锁的语法很简单:
# 获取表锁 LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] ... lock_type: READ [LOCAL] | [LOW_PRIORITY] WRITE # 释放表锁 UNLOCK TABLES
示例
mysql> lock tables t read, t1 write; Query OK, 0 rows affected (0.02 sec) mysql> unlock tables; Query OK, 0 rows affected (0.00 sec)
页锁
页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。
行锁
行级锁定最大的特点就是锁定对象的粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。
由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。行级锁定也最容易发生死锁。
使用行级锁定的主要是InnoDB存储引擎。
总结
-
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
-
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
-
页锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
后面在详细说下Innodb中的各种锁。
五、参考
《MySQL技术内幕》
https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html