数据库的隔离级别(这里以mysql为例)

这里我先简单介绍一下什么是事务

事务是由一组相互依赖的sql语句组成的,这组sql语句要么全部执行成功,中间有一个失败那么事务将会回滚到最开始的状态。事务具有四种特性:ACID,分别是原子性、一致性,隔离性和持久性。(因为这块设计到的知识点比较杂,所以我会在下面对这些知识点做一些简单的介绍)

什么是脏读、不可重复读和幻读

这里的前提是有两个客户端对同一个表中的数据进行增删改操作
脏读:当一个服务端开启了一个事务A,对表中的数据进行更新操作但是未提交数据的时候,这时的数据只是保存在内存中,还未将数据写入磁盘 ,那么这时候另一个事务B进行查询操作,那么B读取到的数据是A未提交的数据,这就是脏读;
不可重复读:当一个事务A对表中的数据进行了更新操作,在未提交的时候另一个事务B开启并查询数据,然后A进行了提交操作,这时候B又进行了查询,这两次查询的数据不一致,这就是不可重复读;
幻读:假如一个表中本来有两条数据。事务A在表中增加了一条数据并提交,事务B想要修改表中的数据全部修改,当执行后,本来应该有显示两条成功,但是却显示的是三条执行成功,明明是两条成功啊,为什么是三条呢?这就是幻读。

事务的隔离级别

简单来说,事务的隔离就是在同一时刻两个事务对同一表中的数据进行操作并且能够互相不影响。在我们的理想状态下,当两个事务同时对表中的数据进行增删改操作的时候,应该是互相不影响的,这也就是我们在上面说到的事务具有隔离性的特性,能不能出现上面所说到的脏读、不可重复读和幻。
在mysql中有四种事务的隔离级别,分别是:READ UNCOMMITTED(读未提交数据)、READ COMMITTED(读已提交数据)、REPEATABLE READ(可重复读)、SERIALIZABLE(串行化),在mysql中默认支持的是第三种。下面我会具体演示在上面说到的前三种隔离级别下数据的安全性。

操作前准备

首先我创建了一个数据库practice,并在库中创建了一张表test,下面是表数据:
在这里插入图片描述

READ UNCOMMITTED(读未提交数据)

然后同时开启两个客户端连接数据库,在两个客户端中同时开启事务对上面所创建的表进行操作。(这里我用不同背景颜色的cmd来代表两个不同的客户端,黑色中开启的事务是上述提到过得事务A,白色开启的事务为事务B)。
在这里插入图片描述

在这里插入图片描述
在这两张图片中,我们发现,当事务A对test表进行了更改操作但是并未commit,这时候的数据是保存在内存中的,还未将数据写入到磁盘。也就是在事务A还未结束的时候事务B对test表进行了查询,这时候读到的数据显然已经被改变了,那如果事务A进行了回滚呢?也就是原始表中的数据最终并未改变,但是在某一时刻事务B读出的数据不是表最终的数据,这种现象也就是我们常说的脏读

READ COMMITTED(读已提交)

在这里插入图片描述

在这里插入图片描述
在上面的操作中,我们可以发现当事务A未进行commit操作的时候事务B进行查询,和事务A commit 操作之后查询,两次的查询结果不一致。这就是我们说的不可重复读
有的小伙伴就会有疑问了,这不是正常嘛,你事务A对表改变了啊,事务B查询出来的东西肯定会不一样啊。这里我大概说一下我个人的见解。类比JAVA中的多线程抢票问题:如果系统中只有一张票,这时苍老师和波波老师同时进行抢票操作,苍老师先抢到票了但是未付款,这时候系统是不是应该显示为没票了?只不过没付款嘛。这时候波波老师来抢票了,一看还有一张挺高兴的,终于能坐车去拍电影了,这时候苍老师完成了支付,波波老师付款的时候却发现票没了,这时候是不是波波老师会很奇怪,明明我抢到票了,为什么付款失败了呢?那么正常情况下是不是苍老师抢到了那张票系统就应该显示没票呢?对吧。个人认为这个情况和上面的情况类似,帮助大家理解。

REPEATABLE READ(可重复读)

在这里插入图片描述
在这里插入图片描述
从上面的操作中我们可以发现,表中的原始数据是两条,当事务A插入一条数据,在未提交的时候事务B进行了查询,显示表中有两条数据,这时候事务A进行commit,这时候事务B再进行更改操作,却发现结果是三行受影响,这时候就会有疑问了,刚刚明明查询出来是两条数据啊,怎么我改了以后却有三行受影响呢?这就是我们所说的幻读。就像你明明看见苍老师在床上躺着,就拖个衣服的时间床上的人变成了面筋哥,你说可怕不可怕。

SERIALIZABLE(序列化)

至于序列化我在这里简单介绍一下,这个是mysql中隔离级别最高的,能够有效的避免上面说的脏读,不可重复读和幻读。再次类比JAVA中的线程,当一个事务进行操作的时候,会进行加锁,知道操作完成才会释放锁,那么别的事务得不到锁,也就不能进行操作,这样数据是安全的的。当然人和事都有两面性,序列化的性能会比较差,就想你在街上见到一个天使面容魔鬼身材的小姐姐,唯一的不足就是下面多了一根。有兴趣的小伙伴可以类比着我上面的操作自己去试一下serializable。

总结

隔离级别脏读不可重复读幻读
read uncommitted
read committed不会
repeatable read不会不会
serializable不会不会不会

希望看到这篇文章的小伙伴多多点赞评论,就当给小编码这么多字的辛苦费吧,哈哈。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值