MySQL事务与Spring事务的隔离级别

MySQL事务

MySQL事务与Spring事务的隔离级别_第1张图片

种类

1.串行化(SERIALIZABLE)
2.可重复读取(REPEATABLE READ)
3.已提交读取(READ commited)
4.未提交读取(read uncommited)

这四种隔离级别由上到下来说 隔离级别逐渐降低,即
串行化(SERIALIZABLE)> 可重复读取(REPEATABLE READ)> 已提交读取(READ commited) > 未提交读取(read uncommited)

但性能方面是反过来的,即隔离级别越低,性能效率越高。
串行化(SERIALIZABLE)< 可重复读取(REPEATABLE READ)< 已提交读取(READ commited)< 未提交读取(read uncommited)

概念:

1.未提交读取(READ UNCOMMITED)

解释:一个事务可以读取到另一个事务中未提交的数据。容易出现脏读等现象。

一个事务读到另一个事务还没有提交的数据。如果另一个事务失败了,回滚了,那么第一个事务读到的数据就是无效的数据。这就是脏读。
举个例子,一个学生在成绩管理系统查询自己的成绩,与此同时,老师正在给该学生登分,本来该学生的成绩是95分,但老师手滑了一下,将成绩登成了98分,但老师在该事务提交之前意识到自己输错了成绩,立马回滚,将成绩改成95分。如果学生正好在老师回滚前进入成绩管理系统,将会看到自己的成绩是98分。这个场景就是学生读到了脏数据,也被称为脏读。

2.已提交读取(READ COMMITED)

解释:一个事务只能读取到其他已经提交后的事务的数据。会出现不可重复读的现象。该级别也是大多数据库的默认事务隔离级别。

READ COMMITTED 隔离级别的安全性比 REPEATABLE READ 隔离级别的安全性要差。处于 READ COMMITTED 级别的事务可以看到其他事务对数据的修改。也就是说,在事务处理期间,如果其他事务修改了相应的表,那么同一个事务的多个 SELECT 语句可能返回不同的结果。
一个事务多次读取表中的某一行数据,每次读取结果都有所差异,原因是另一个事务的提交更新了该行数据
举个例子,又是这个学生在成绩管理系统查询自己的成绩,此时老师还没有登分上去,所以学生看见自己的成绩为null,此后老师登录系统,为该学生登上成绩95分,并顺利提交该事务。学生过了一会后再取查询自己的成绩,发现自己的成绩为95分。

3.可重复读取(REPEATABLE READ)

解释:在可重复读在这一隔离级别上,事务不会被看成是一个序列。不过,当前正在执行事务的变化仍然不能被外部看到,也就是说,如果用户在另外一个事务中执行同条 SELECT 语句数次,结果总是相同的。(因为正在执行的事务所产生的数据变化不能被外部看到,容易出现幻读现象。)

幻读:在一个事务中,执行同一条select语句,每次的读取结果不是多一些数据行就是少一些数据行,该原因是在该事务中不断执行同一条事务的时间段内,其他的事务成功提交更新了数据表,导致可能新增了几行数据,或者减少了几行数据。
举个例子,还是这个学生,去某宝上买Mysql相关的书,于是搜索Mysql,发现一共有20000+条结果,过了一会儿他又再次搜索Mysql关键字,发现这次有21000+条结果,原因是在该学生两次搜索的间隔中,又有一些商家上架了Mysql相关的书籍并成功提交事务,导致搜索结果增加。又过了一会儿,该学生再次搜索Mysql,发现只有18000+条结果,原因是这段时间间隔之间,有3000+本Mysql书籍售罄了,商家下架了这些书籍并成功提交事务,导致搜索结果减少。

值得一提的是,可重复读取(REPEATABLE READ)是MySQL默认的事务隔离级别。

4.串行化(SERIALIZABLE)

解释:所有事务被看成一个序列。通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。通俗地讲就是,假如两个事务都操作到同一数据行,那么这个数据行就会被锁定,只允许先读取/操作到数据行的事务优先操作,只有当事务提交了,数据行才会解锁,后一个事务才能成功操作这个数据行,否则只能一直等待,该隔离级别可能导致大量的超时现象和锁竞争。该隔离级别也是最高的隔离级别,它提供了事务之间最大的隔离限度。

举个例子来说,有一个学生想去网吧上网,他通过手机准备预订某家网咖的位置,发现还有最后一个位置没被预订,正当他准备预订该位置时,发现链接无法点进去,该学生以为自己网络不好,于是退出重新进入预订系统,发现该位置已被预订,原因是在该学生准备订下该位置时,有另一个学生比他先一步成功预订了该位置,并且已经成功提交事务,导致该学生无法进入预订该位置的链接,因为已经有一个比他先操作该链接的事务占用了该数据行,导致后续的事务必须要等待前一个事务操作完成才能访问该数据行。

不可重复读与幻读的区别

两者非常相似,都是每次读取时,读取的结果不同。
但不可重复读针对的是表中的某一行数据,而幻读针对的是多行数据。

四种事务隔离级别一览:

MySQL事务与Spring事务的隔离级别_第2张图片

Spring事务的隔离级别

总共五种,除了上述四种以外,还有spring后端使用的数据库的默认事务隔离级别。

图片来源:
https://blog.csdn.net/qq_39940205/article/details/120149988

参考链接:
https://blog.csdn.net/jason_jiahongfei/article/details/106055836
https://blog.csdn.net/qq_39940205/article/details/120149988

你可能感兴趣的:(MySQL,mysql,spring)