MySQL事务和锁实战

Posted by zsh on September 20, 2021

网上关于事务和锁的理论知识文章非常丰富,但是每次看完总是很容易忘记,死记硬背也没什么意义,还不如实际操作一次,让自己印象更深刻。

此次实验准备了一张非常简单的表,数据库版本为5.7.x

1
2
3
4
5
create table user 
(
	id int,
	name varchar(255)
)

首先从RC隔离级别开始,在RC级别下是只能读取到其他事务提交后的数据。

多事务读-写下,RC隔离等级未发生不可重复读,但是发生了幻读。那么在多事务写-写下的表现是怎么样的

先更新的事务获取到了锁,因此后更新的事务需等待锁的释放才可以更新成功,同时RC等级下insert是不会阻塞的

接下来观察RR等级下的表现,实验步骤和上面一模一样

可以看到没有出现幻读了,而其他表现与RC级别一致

接着来看锁相关的实验,事务隔离级别为RR,首先是表锁

表读锁会阻塞写,不会阻塞读,表写锁会阻塞读写。跟行锁里的共享锁(S)和排他锁(X)行为一致

然后是行锁,因为行锁输基于索引的,所以我们给id列加上索引

加锁的列为索引时

加锁的列不是索引

可以看到加的都是行锁,没有出现表锁,所以在加锁时如果索引失效导致对整张表加锁的情况下,用的还是行锁,只不过锁的范围说整张表

总结:锁的最终目的都是在并发下保证数据的正确性。MySQL使用的解决方案是读使用乐观锁(MVCC),写使用悲观锁(排他锁)