理解事务隔离级别,看这一篇就够了,看完还不懂打死我(附个人理解图解)

事务隔离级别分为:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)

在理解事务隔离之前,我们得先知道,为什么会存在事务隔离,是因为在之前的问题中,出现了脏读,幻读,不可重复读。接下来我们先介绍一下这几种并发控制问题吧。

1. 并发控制问题

1.1 脏读

        定义:脏读指的是一个事务读取了另一个事务中未提交的数据。也就是说,如果事务A正在修改某些数据但尚未提交,而事务B读取了这些数据,那么B读取到的可能是A回滚前的临时数据。
        后果:由于事务A可能回滚,事务B读取到的数据实际上是不存在的,这会导致B基于错误的数据做出决策。

        看这个定义是不是很迷糊,我说说我的理解吧,首先,产生脏读需要两个条件,1,两个或多个事务,2,读取其他事务未提交的数据。这两个条件缺一不可。脏读就是事务A和事务B同时操作一条数据,A在B还没有提交时读取了数据,在读取之后,B又对数据进行了更改(事务回滚,更新,插入,删除等),这里A就产生了脏读。如果还不理解,可以看看下面的一张图解。

1.2 不可重复读

这里我故意将脏读和不可重复读挨放在一起,是因为这两者有相似之处。

定义:不可重复读是指在一个事务中,多次读取同一数据时,发现数据被其他事务修改了。即事务A在读取某条记录后,事务B修改了这条记录,然后A再次读取时,发现数据已经变化。
后果:这会导致事务A在执行过程中得到不一致的数据,从而影响其决策和操作结果。

如果你理解了脏读,那么不可重复读便很好理解了。因为脏读就是读取了一次数据,导致读取到了错误的数据并提交,这里的重点在于:只读取一次,并且提交了错误数据。不可重复读重点在于:读取了两次或多次数据,两次或多次数据不一样,这便是不可重复读。这里的重点在于:多次读取数据得到的数据不一样。反而对是否提交到不那么重要。大家如果还没有理解,我画了一张图。

1.3 幻读

我将幻读和不可重复读放在一起,因为他们也有相似之处。

定义:幻读发生在事务执行过程中,一个事务对同一范围的数据进行了两次查询,两次查询的结果不一致,因为在此期间有其他事务插入或删除了数据。
后果:事务可能会基于第一次查询的结果做出决策,而在后续操作时发现数据已经改变,导致不一致的结果。

如果你理解了不可重复读,那么幻读便不难。不可重复读是多次读取数据,得到的数据不一样。而幻读也是多次读取,但是幻读读取的是数据范围,多次读取得到的数据量不一样,这里我们总结一下,幻读读取的是数据范围,前后数据量不一致。

2. 事务隔离级别

事务隔离级别分为:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)

2.1 读未提交

这是最低等级的事务隔离,在这种隔离级别下,事务可以读取到其他事务未提交的数据。这意味着可能会发生“脏读”现象,即读取到其他事务回滚后被删除的数据。

也就是说,这个等级相当于啥都不干,安全等级最低

2.2 读已提交

这种隔离级别要求事务在提交之前,其他事务不能读取它。因此,一个事务只能读取到其他事务已经提交的数据,避免了脏读。但是,这可能导致“不可重复读”问题,即同一个事务在不同时间点读取同一数据时,返回的结果可能不同。

读已提交可以防止脏读,因为他读取的数据一定是已提交的数据,他在读取前会进行判断,所以一定不会产生脏读。

读已提交不能防止不可重复读,那是因为当读取开始后,其他事务就可以对目前正在读取的数据进行操作改动等,所以不能防止不可重复读。

这里大家就有个盲点或者疑问,不是说在事务之前其他事务不能读取它嘛,怎么还会出现在读取时修改数据,也就是不可重复读的问题呢?不知道大家想到这个问题没有,我查了好久的资料,终于理解了这个问题。

原因是: 他的的确确不能读取未提交的事务(不能读取到事务A),但是他能读取前一个事务的提交(能读取到事务B)。这里我们假设事务A读取了数据D,这个数据D上一次被事务B操作过并且已经提交了,所以这时候事务A读取的数据D是事务B提交过的,但事务A开始读取后,事务C还是可以操作数据D,导致不可重复读。        总结一下,前面所说的 事务提交之前,其他事务不能读取它,代表的是事务C不能读取到事务A修改的数据,而不是事务C不能读取 数据D 这个对象,但是事务C依旧可以读取到事务B提交的数据C,大家理解了吗?

2.3 可重复读

在可重复读隔离级别下,事务开始后,其他事务只能读取已提交的数据,不能修改已读取的数据。因此,一个事务在执行过程中读取的数据保持不变,避免了脏读和不可重复读。但是,这可能导致“幻读”问题,即在事务中插入或删除数据后,再次执行相同查询时,查询结果的行数发生了变化。

可重复读也是mysql默认的事务隔离等级。

可重复读相当于在读取数据期间,对该数据加上了一个读锁,其他事务不能对该数据进行修改,所以他能够防止不可重复读,他多次读取数据都是一样的。不知道上面读已提交我举的小问题大家是否理解,如果理解了,那可重复读就是在事务A开始操作数据D后,事务C不能修改数据D,且事务C读取到的数据D是事务B提交的,跟事务A没有关系。

可重复读不能防止幻读,之前我们说到相当于给数据加了一个读锁,但是只是对数据加锁,数据间可以进行插入等操作,导致会出现前后查询的总数据量不一样,导致幻读。

2.4 串行化(序列化)

这是最高的事务隔离级别,它通过为每个事务分配一个唯一的序列号,并按照这个序列号的顺序执行事务,从而保证了事务的顺序执行。这种方式可以避免脏读、不可重复读和幻读,但可能会导致并发性能的下降,因为所有事务都需要按照顺序执行,可能需要等待其他事务完成。

这是最高等级,也是最安全的事务隔离等级,意思是他不允许多个事务同时运行,从根源上解决了所有并发问题。不过性能很低,一般来说,除了像银行这样需要非常精确的场景,一般都不用。

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值