面试问题:
1、高并发场景下如何保证数据一致性和事务隔离性
2、了解Mysql的锁机制吗
1、Mysql锁的划分
Mysql的锁根据锁的粒度可以分为:全局锁、表锁和行锁,在思想上可以分为悲观锁和乐观锁
- 粒度
- 全局锁
- 表锁
- 表锁
- 表共享读锁
- 表独占写锁
- 元数据锁
- 意向锁
- 意向共享锁
- 意向排他锁
- 表锁
- 行锁
- 共享锁
- 排他锁
1.1 全局锁(锁粒度最大)
锁定数据库中的所有表
1.2 表锁
每次操作时锁住整张表,锁粒度大,发生锁冲突的概率最高,并发度最低,应用在MyISAM、InnoDB、BDB等存储引擎中
1.2.1 InnoDB下的表锁分类
-
表锁
- 表共享读锁(read lock)
读锁不会阻塞其它客户端的读,但会阻塞其它客户端的写
lock tables 表名 read; //客户端1 只能读不能写,不阻塞客户端2的读操作,但阻塞写操作 //释放锁 unlock tables;
- 表独占写锁(write lock)
写锁既阻塞其它客户端的读,也会阻塞其它客户端的写
lock tables 表名 write; //客户端1既可以写也可以读,客户端2不能写也不能读 unlock tables; //客户端2既可以读也可以写
- 表共享读锁(read lock)
-
元数据锁(meta Data lock,MDL)
-
意向锁
为了让行级锁定和表级锁定共存,InnoDB也同样使用了意向锁(表级锁定)的概念,也就有了意向共享锁和意向排他锁这两种。意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁;事务可以通过以下语句显示给记录集加共享锁或排他锁。共享锁(S):SELECTFROM table_name WHERE … LOCK IN SHARE MODE
排他锁(X):SELECTFROM table_name WHERE … FORUPDATE
1.3 行锁(锁粒度最小)
每次操作锁住对应的行数据,锁定粒度最小,发生冲突的概率最低,并发度最高,应用在InnoDB存储引擎中
1.3.1 InnoDB锁的算法有哪些
-
- Record lock:单个⾏记录上的锁;record lock 永远锁的是索引,而非数据本身,如果innodb表中没有索引,那么会自动创建一个隐藏的聚集索引,锁住的就是这个聚集索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。
-
- Gap lock:间隙锁,锁定⼀个范围,不包括记录本身;
-
- Next-key lock:record+gap 锁定⼀个范围,包含记录本身。
- Next-key lock:record+gap 锁定⼀个范围,包含记录本身。
1.3.2 共享锁和排他锁
共享锁
什么是共享锁?
共享锁又称读锁 (read lock),是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。当如果事务对读锁进行修改操作,很可能会造成死锁。
排他锁
排他锁 exclusive lock(也叫 writer lock)又称写锁,排它锁是悲观锁的一种实现。
若某个事物对某一行加上了排他锁,只能这个事务对其进行读写,在此事务结束之前,其他事务不能对其进行加任何锁,其他进程可以读取,不能进行写操作,需等待其释放。