MySQL 锁效果演示
Innodb存储引擎:
- 共享锁
- 排他锁
insert、delete、update会默认上排他锁;
select * from table for update;为排他锁
select * from table lock in share mode
为共享锁
案例准备
create database test;
use test;
create table tab_with_idx(id int(3),name varchar(10));
insert into tab_with_idx values (1,"11");
insert into tab_with_idx values (2,"2");
`温馨提示:每个命令都要以分号为结束;才会被解析执行`
- 登陆mysql – 使用mysql -uroot -p命令,再输入密码;/或者 直接mysql -uroot -p123456(假设123456为密码)
- autocommit默认打开,需要先关闭,才能看到效果 –
set autocommit = 0;
共享锁
select * from tab_with_idx lock in share mode;
update tab_with_idx set name = "1" where id = 1;
select * from tab_with_idx;
`本质就是读锁,为了实现不同事务都可以进行读取(当前读)的操作`
`获取锁的会话执行commit语句即释放锁`
- 如果获取该表的锁的会话当前只有一个
- 他具有修改数据的权限:因为该会话可以成功获取到了独占锁,共享锁变成了独占锁,其他会话只能读不能写
- 在没有变成独占锁前,其他会话可以加共享锁,都能进行当前读的操作
- 一旦变成了独占锁,其他会话就无法加共享锁
- 如果不止一个,只能进行读取,都不能进行修改
- 修改需要等待对方释放锁,等待锁释放超时,mysql会自动解除
锁的叠加 – 读锁可以加读锁,写锁与其他锁都不能兼容;
RC 和 RR 级别的 MVCC
在 RC读已提交
和 RR可重复读
隔离级别下
-
RC级别下,每次语句执行的过程,即每查询一次就生成一次Read View
- RC仍存在不可重复读,就是因为每次查询都生成一次,假设事务A先查询了一次tab表,然后事务B进行了修改并提交,此时A再一次查询得到的结果与原来不同,造成了不可重复读
-
RR级别下,同一个事务中的第一次快照读才生成Read View
新建一个新的表
create table tab(id int(1),age tinyint(3));
insert into tab values(1,11),(2,22);
select @@transaction_isolation;
设置隔离级别为RC
set session transaction isolation level read committed;
设置隔离级别为RR -- 默认隔离级别
set session transaction isolation level repeatable read;
RC 隔离级别下 演示
RR 隔离级别下 演示
生成read view的时机是在第一次查询语句时生成,而不是事务开启的时机
根据演示,我们也可以得知RC隔离级别下仍存在不可重复读现象,而RR隔离级别下并不存在