mysql 锁隔离级别_mysql中隔离级别和锁有什么关系?

数据库事务有不同的隔离级别,不同的隔离级别对锁的使用是不同的,锁的应用最终导致不同事务的隔离级别

MVCC(Multi-Version Concurrency Control)多版本并发控制,可以简单地认为:MVCC就是行级锁的一个变种(升级版)。事务的隔离级别就是通过锁的机制来实现,只不过隐藏了加锁细节

在表锁中我们读写是阻塞的,基于提升并发性能的考虑,MVCC一般读写是不阻塞的(所以说MVCC很多情况下避免了加锁的操作)MVCC实现的读写不阻塞正如其名:多版本并发控制--->通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。从用户的角度来看,好像是数据库可以提供同一数据的多个版本。

快照有两个级别:语句级针对于Read committed隔离级别

事务级别针对于Repeatable read隔离级别

我们在初学的时候已经知道,事务的隔离级别有4种:Read uncommitted会出现脏读,不可重复读,幻读

Read committed会出现不可重复读,幻读

Repeatable read会出现幻读(但在Mysql实现的Repeatable read配合gap锁不会出现幻读!)

Serializable串行,避免以上的情况!

Read uncommitted会出现的现象--->脏读:一个事务读取到另外一个事务未提交的数据例子:A向B转账,A执行了转账语句,但A还没有提交事务,B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。A回滚事务【rollback】,等B再查看账户的钱时,发现钱并没有多。

出现脏读的原因是因为在读的时候没有加读锁,导致可以读取出还没释放锁的记录。

Read uncommitted过程:事务A读取记录(没有加任何的锁)

事务B修改记录(此时加了写锁,并且还没有commit-->也就没有释放掉写锁)

事务A再次读取记录(此时因为事务A在读取时没有加任何锁,所以可以读取到事务B还没提交的(没释放掉写锁)的记录

Read committed避免脏读的做法其实很简单:在读取的时候生成一个版本号,直到事务其他commit被修改了之后,才会有新的版本号

Read committed过程:事务A读取了记录(生成版本号)

事务B修改了记录(此时加了写锁)

事务A再读取的时候,是依据最新的版本号来读取的(当事务B执行commit了之后,会生成一个新的版本号),如果事务B还没有commit,那事务A读取的还是之前版本号的数据。

但Read committed出现的现象--->不可重复读:一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改注:A查询数据库得到数据,B去修改数据库的数据,导致A多次查询数据库的结果都不一样【危害:A每次查询的结果都是受B的影响的,那么A查询出来的信息就没有意思了】

上面也说了,Read committed是语句级别的快照!每次读取的都是当前最新的版本!

Repeatable read避免不可重复读是事务级别的快照!每次读取的都是当前事务的版本,即使被修改了,也只会读取当前事务版本的数据。

呃...如果还是不太清楚,我们来看看InnoDB的MVCC是怎么样的吧(摘抄《高性能MySQL》)

至于虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。注:和不可重复读类似,但虚读(幻读)会读到其他事务的插入的数据,导致前后读取不一致

MySQL的Repeatable read隔离级别加上GAP间隙锁已经处理了幻读了。

关注我的公众号:Java3y,获取更多资料~

帮助到你了?点赞!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值