0
点赞
收藏
分享

微信扫一扫

AI与技术美术(TechArt)

春意暖洋洋 04-05 07:00 阅读 2

上一章Mysql的事务-CSDN博客讲了MySQL的事务,事务就是两个不同的线程在操作同一个数据库,而事务的本质就是锁,通过调节事务的不同的隔离等级来解决脏写、脏读、不可重复读以及幻读问题,就是在不同的隔离级别上使用不同的锁实现的,也就是说,数据库的锁机制本身是为了解决并发事务带来的问题而诞生的。

1 MySQL锁的分类

在这里插入图片描述

2 不同隔离级别的锁类型

在这里插入图片描述## 2.1 准备数据

-- 创建学生表
CREATE TABLE users (
	id INT auto_increment NOT NULL,
	user_no varchar(100) NULL COMMENT '用户编号',
	name varchar(100) NULL COMMENT '用户名字',
	age INT NULL COMMENT '用户年龄',
	CONSTRAINT students_PK PRIMARY KEY (id)
);

--插入学生数据
INSERT INTO users (user_no, name, age) VALUES
('1', '小红', 10),
('2', '小蓝', 11),
('3', '小黑', 13),
('4', '小白', 14);

2.2 读未提交

-- 设置隔离级别
set global transaction isolation level read uncommitted;

--事务1
start transaction;
select * from users;
update users set age=age+1 where name="小红";
commit;

--事务2
start transaction;
select * from users;
update users set age=age+1 where name="小红";
commit;

在这里插入图片描述
如图所示,两个事务同时读取数据的时候并没有加锁,而同时修改实际的时候事务开始阻塞,等事务1commit之后才执行成功。

-- 查询innodb状态日志
show engine innodb status\G;

--表级的意向排它锁(IX):lock mode IX。
--表级的插入意向锁(LOCK_INSERT_INTENTION): lock_mode X locks gap before rec insert intention
--行级的记录锁(LOCK_REC_NOT_GAP): lock_mode X locks rec but not gap
--行级的间隙锁(LOCK_GAP): lock_mode X locks gap before rec
--行级的 Next-key 锁(LOCK_ORNIDARY): lock_mode X

在这里插入图片描述
通过查看日志可知,同时读取数据并未加锁,而同时更新数据加的是记录锁,而且是写排他锁,同时写入会阻塞。

2.3 读已提交

-- 设置隔离级别
set global transaction isolation level read committed;
--事务1
start transaction;
select * from users;
update users set age=age+1 where name="小蓝";
commit;

--事务2
start transaction;
select * from users;
update users set age=age+1 where name="小蓝";
commit;

在这里插入图片描述
如图所示,两个事务同时读取数据的时候并没有加锁,而同时修改实际的时候事务开始阻塞,等事务1commit之后才执行成功。和读未提交现象一致,两者区别是读已提交是通过MVCC来读已提交的内容。

-- 查询innodb状态日志
show engine innodb status\G;

--表级的意向排它锁(IX):lock mode IX。
--表级的插入意向锁(LOCK_INSERT_INTENTION): lock_mode X locks gap before rec insert intention
--行级的记录锁(LOCK_REC_NOT_GAP): lock_mode X locks rec but not gap
--行级的间隙锁(LOCK_GAP): lock_mode X locks gap before rec
--行级的 Next-key 锁(LOCK_ORNIDARY): lock_mode X

在这里插入图片描述
通过查看日志可知,同时读取数据并未加锁,而同时更新数据加的是记录锁,而且是写排他锁,同时写入会阻塞。

2.4 可重复读

-- 设置隔离级别
set global transaction isolation level repeatable read;
--事务1
start transaction;
select * from users;
update users set age=age+1 where name="小黑";
commit;

--事务2
start transaction;
select * from users;
update users set age=age+1 where name="小黑";
commit;

在这里插入图片描述
如图所示,两个事务同时读取数据的时候并没有加锁,而同时修改实际的时候事务开始阻塞,等事务1commit之后才执行成功。和读未提交现象一致,两者区别是读已提交是通过MVCC来读已提交的内容。

-- 查询innodb状态日志
show engine innodb status\G;

--表级的意向排它锁(IX):lock mode IX。
--表级的插入意向锁(LOCK_INSERT_INTENTION): lock_mode X locks gap before rec insert intention
--行级的记录锁(LOCK_REC_NOT_GAP): lock_mode X locks rec but not gap
--行级的间隙锁(LOCK_GAP): lock_mode X locks gap before rec
--行级的 Next-key 锁(LOCK_ORNIDARY): lock_mode X

在这里插入图片描述
通过查看日志可知,同时读取数据并未加锁,可重复读写加的是临键锁,而且是写排他锁,同时写入会阻塞

2.5 串行化

-- 设置隔离级别
set global transaction isolation level serializable;
--事务1
start transaction;
select * from users;
update users set age=age+1 where name="小白";
commit;

--事务2
start transaction;
select * from users;
update users set age=age+1 where name="小白";
commit;

在这里插入图片描述
在这里插入图片描述
如图所示,读-读可以同时进行,但是读-写和写-写是不能同时进行的,表明读是共享锁,写是排他锁

-- 查询innodb状态日志
show engine innodb status\G;

--表级的意向排它锁(IX):lock mode IX。
--表级的插入意向锁(LOCK_INSERT_INTENTION): lock_mode X locks gap before rec insert intention
--行级的记录锁(LOCK_REC_NOT_GAP): lock_mode X locks rec but not gap
--行级的间隙锁(LOCK_GAP): lock_mode X locks gap before rec
--行级的 Next-key 锁(LOCK_ORNIDARY): lock_mode X

在这里插入图片描述
日志可以看出锁的类型也是临键锁

举报

相关推荐

0 条评论