数据库锁

锁模块常见问题

1、MyISAM与InnoDB关于锁方面的区别是什么?

1.1、MyISAM默认表级锁,不支持行级锁

查询表的时候上锁,更新这个表的查询外的数据需要等待,但是同事间其他查询是可以的,说明myisam是共享锁

读锁(共享锁)

显式给myisam表加读锁(共享锁)
lock tables person_myisam read;(或者write 上读锁或者写锁)
unlock tables;

写锁(排它锁)

显式给select加上排它锁  加上for update
select * from person_myisam where id between 1 and 1000 for update;

myisam适合的场景

频繁执行全表count语句

对数据进行增删改的频率不高,查询非常频繁

没有事务

1.2、InnoDB默认行级锁,支持表级锁

注意innodb是二段锁,提交语句的时候会上锁,commit提交后会解锁。

在执行语句前要将每个session会话框的自动提交关闭

show variables like 'autocommit';
set autocommit =0;
显式加上共享读锁 (lock in share mode) 
select * from person_innodb where id= 3 lock in share mode;
update person_innodb set name='lihua' where id =4;
在发现更新操作可以成功,说明innodb是行锁

当查询没有索引的数据时,用的时表级锁,非当前的查询数据也无法被更新

适合的场景

数据增删改查都相当频繁

可靠性要求比较高,要求支持事务

1.3、共享锁和排它锁的兼容性

X S
X 冲突 冲突
S 冲突 兼容

总结:

查询的时候加上表级别的读锁,增删改的时候加上表级别的写锁,读锁和写锁是互斥的。相当于只有一个坑位

共享锁遇到共享锁的时候是可以执行的,一旦先上了排他锁,就不能执行新的操作。

1.4、数据库锁的分类

按锁的粒度划分,可分为表级锁、行级锁、页级锁

按锁级别划分,可分为共享锁、排它锁

按加锁方式划分,可分为自动锁、显式锁按操作划分,可分为DML锁、DDL锁(DML就是增删改查,DDL就是对表结构操作)

按使用方式划分,可分为乐观锁、悲观锁

2、事务隔离级别以及各级别下的并发访问问题?

2.1、数据库事务的四大特性ACID

原子性(automic) 事务包含的所有操作要么全部执行,要么回滚全都不做

一致性(consistency)比如转账,两个人账户互相转账总金额是不变的

隔离性(Isolation)多个事务并发执行时,一个事务的执行不应该影响其他事务的执行

持久性(Durability)一个数据被提交后,数据永远不变

2.2、更新丢失

mysql所有事务隔离级别在数据库层面上均可避免

2.3、脏读

脏读就是一个事务读到另一个事务未提交的数据(未提交的数据可能会回滚rollback)

READ-COMMITTRD事务隔离级别以上可避免

image-20211216113407662

查看当前session的事务隔离级别
select @@transaction_isolation;
默认是REPEATABLE-READ


设置当前session的事务隔离级别  read uncommitted 是最低的事务隔离级别
set session trasaction isolation level read uncommitted;

解决方式,将事务隔离级别设置成read committed 也就是数据查询读取到的数据都是以及提交了的数据

也就是说处理相同的数据时,未提交的事务无论怎么改动这个数据,都不影响另一个session对这个数据的处理

2.4、不可重复读

就是事务A多次读取同一数据,事务B在A读取的时候进行了提交,也就是事务A读取的结果不一致

将隔离级别设置成可重读
set session trasaction isolation level repeatable read;

2.5、幻读

事务A读取与搜索条件相同的若干行数据,事务B通过修改A的数据集,导致事务A看起来像出现幻觉

将隔离级别设置成最高的serializable
set session trasaction isolation level serializable;

image-20211216140810369

3、InnoDB可重复读隔离级别下如何避免幻读?

当前读和快照读

当前读∶select…lock in share mode,select.for update (当前读的crud,对读取的记录加锁)

当前读∶update,delete, insert (当前读的crud,对读取的记录加锁)

快照读∶不加锁的非阻塞读,select

快照读读到的数据可能不是最新版本,是历史版本

创建快照的时机决定了数据的展示值

4、RC、RR级别下的InnoDB的(快照读)非阻塞读如何实现?

repeat committed RC

repeat read RR

RR级别下的InnoDB的(快照读)非阻塞读

image-20211216144646220

只有RR以及以上才支持gap锁(间隙锁)

对主键索引或者唯一索引会用Gap锁吗

如果where条件全部命中,则不会用Gap锁,只会加记录锁

如果where条件部分命中或者全部不命中,则用gap锁

5、语法

group by

image-20211216152001029

having

通常与group by 连用

出现在同一sql中的顺序:where>group by >having

count,sum,max,min,avg

6、范式

原文地址:https://www.cnblogs.com/yslu/p/15698880.html