JAVA全系列 教程
3762个小节阅读:7088k
目录
C语言快速入门
JAVA全系列 教程
面向对象的程序设计语言
Python全系列 教程
Python3.x版本,未来主流的版本
人工智能 教程
顺势而为,AI创新未来
大厂算法 教程
算法,程序员自我提升必经之路
C++ 教程
一门通用计算机编程语言
微服务 教程
目前业界流行的框架组合
web前端全系列 教程
通向WEB技术世界的钥匙
大数据全系列 教程
站在云端操控万千数据
AIGC全能工具班
A A
White Night
从本质上讲,锁是一种协调多个进程或多个线程对某一资源的访问的机制,MySQL使用锁和MVCC机制实现了事务隔离级别。
顾名思义,悲观锁对于数据库中数据的读写持悲观态度,即在整个数据处理的过程中,它会将相应的数据锁定。在数据库中,悲观锁的实现需要依赖数据库提供的锁机制,以保证对数据库加锁后,其他应用系统无法修改数据库中的数据。
注意:
在悲观锁机制下,读取数据库中的数据时需要加锁,此时不能对这些数据进行修改操作。修改数据库中的数据时也需要加锁,此时不能对这些数据进行读取操作。
悲观锁会极大地降低数据库的性能,特别是对长事务而言,性能的损耗往往是无法承受的。乐观锁则在一定程度上解决了这个问题。
注意:
实现乐观锁的一种常用做法是为数据增加一个版本标识,如果是通过数据库实现,往往会在数据表中增加一个类似version的版本号字段。
读锁又称为共享锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
写锁又称为排他锁,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
注意:
需要注意的是,对同一份数据,如果加了读锁,则可以继续为其加读锁,且多个读锁之间互不影响,但此时不能为数据增加写锁。一旦加了写锁,则不能再增加写锁和读锁。因为读锁具有共享性,而写锁具有排他性。
表锁也称为表级锁,就是在整个数据表上对数据进行加锁和释放锁。典型特点是开销比较小,加锁速度快,一般不会出现死锁,锁定的粒度比较大,发生锁冲突的概率最高,并发度最低。
手动增加表锁
xxxxxxxxxx
mysql> lock table userinfo read;
Query OK, 0 rows affected (0.00 sec)
mysql> lock table userinfo write;
Query OK, 0 rows affected (0.00 sec)
查看数据表上增加的锁
xxxxxxxxxx
show open tables;
删除表锁
xxxxxxxxxx
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
行锁也称为行级锁,就是在数据行上对数据进行加锁和释放锁。典型特点是开销比较大,加锁速度慢,可能会出现死锁,锁定的粒度最小,发生锁冲突的概率最小,并发度最高。
注意:
- 行锁主要加在索引上,如果对非索引的字段设置条件进行更新,行锁可能会变成表锁。
- InnoDB的行锁是针对索引加锁,不是针对记录加锁,并且加锁的索引不能失效,否则行锁可能会变成表锁。
- 锁定某一行时,可以使用lock in share mode命令来指定共享锁,使用for update命令来指定排他锁,例如下面的SQL语句。
select * from userinfo where id = 1 for update;
页面锁也称为页级锁,就是在页面级别对数据进行加锁和释放锁。对数据的加锁开销介于表锁和行锁之间,可能会出现死锁,锁定的粒度大小介于表锁和行锁之间,并发度一般。
在MySQL中使用范围查询时,如果请求共享锁或排他锁,InnoDB会给符合条件的已有数据的索引项加锁。如果键值在条件范围内,而这个范围内并不存在记录,则认为此时出现了“间隙(也就是GAP)”。InnoDB存储引擎会对这个“间隙”加锁,而这种加锁机制就是间隙锁(GAP Lock)。
例如,userinfo数据表中存在如下数据。
xxxxxxxxxx
mysql> select * from userinfo;
+----+-------+---------+
| id | name | balance |
+----+-------+---------+
| 1 | Java | 100.00 |
| 2 | MySQL | 200.00 |
| 3 | Spring | 300.00 |
| 15 | Netty | 400.00 |
| 20 | Dubbo | 500.00 |
+----+-------+---------+
2 rows in set (0.00 sec)
update userinfo set balance = balance + 100 where id > 5 and id < 16.
解释:
此时,userinfo数据表中的间隙包括id为(3,15]、(15,20]、(20,正无穷]的三个区间。如果执行如下命令,将符合条件的用户的账户余额增加100元。 update userinfo set balance = balance + 100 where id > 5 and id <16; 则其他事务无法在(3,20]这个区间内插入或者修改任何数据。 这里需要注意的是,间隙锁只有在可重复读事务隔离级别下才会生效。
临键锁(Next-Key Lock)是行锁和间隙锁的组合,例如上面例子中的区间(3,20]就可以称为临键锁。
实时效果反馈
1.MySQL使用__和MVCC机制实现了事务隔离级别。
A CAS
B APS
C 锁
D 以上都错误
2. 从性能上看,MySQL中的锁可以分为悲观锁和乐观锁,这里的乐观锁是通过____对比来实现的。
A 版本
B 数据库锁机制
C CAS
D 以上都是错误
答案
1=>C 2=>A