第一题
软件环境描述:
Mysql V5.7.30 Innodb RR隔离级别
表结构以及数据描述:
(1)t_user用户表,表格如下:
CREATE TABLE t_user (
id int(10) NOT NULL,
name varchar(100) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
(2)表里面存量数据:
业务场景描述
事务1 | 事务2 |
begin; select * from t_user | |
begin; insert into t_user values (20,'bole'); commit; | |
update t_user set name='zhuge' where id=20; | |
select count(*) from t_user | |
commit; |
问题: 请问事务1 的第二次(红色sql)查询结果是什么?为什么?
4,事务2新增数据提交之后,事务1更新的当前读是可以操作成功,根据可见性规则:当前事务更新的数据对当前事务是可见的。所以事务1的第2个查询是可以读到id=20这条数据,再加上快照里面的3条数据,一共就是4条数据。
第二题
软件环境描述:
Mysql V5.7.30 Innodb RR隔离级别
表结构以及数据描述:
(1)t_user用户表,表格如下:
CREATE TABLE t_user (
id int(10) NOT NULL,
name varchar(100) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
(2)表里面存量数据:
业务场景描述
事务1 | 事务2 | 事务3 |
begin; insert into t_user values (20,'bole'); | ||
begin; insert into t_user values (20,'bole'); | ||
begin; insert into t_user values (20,'bole'); | ||
Rollback; | ||
问题: 请问三个事务是否能够正常执行?说说你的理解。
事务1正常执行,事务2和3形成死锁,有一个事务会被中止。
- 1、事务1会给表id20行加入X锁
- 2、事务2、3给id20行加入X锁发现这行记录已经被锁了,由于主键唯一性,事务2、3会转为S锁(注意是X->S,不会给该记录行加上锁,这时事务1已经给id20行加上了X锁)
- 3、当事务1回滚,事务2、3同时持有id20行的S锁,并且因为存储引擎为了保证插入数据的操作安全性,将S锁升级为GAP锁(间隙锁)
- 4、与此同时,事务2、3同时向表id20行申请插入意向锁(IX锁),因为此时两个事务都持有S锁,那么因为IX锁与S锁不兼容,所以两个事务互相等待对方释放S锁,形成了死锁
- 5、数据库发现死锁后,自动中止其中一个事务。
答案拆解
首先我们需要知道锁的关系
http://t.csdnimg.cn/FP6Adhttp://t.csdnimg.cn/FP6Ad
因为主键唯一性,会将原本需要加入X锁的操作转变为S锁
根据锁的关系,我们知道IX与S锁是不兼容的,因此会造成死锁!