数据库事务的隔离级别

发布时间:2022-07-01 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了数据库事务的隔离级别脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。  --百度百科

众所周知,事务有ACID特性(原子性、一致性、隔离性、持久性),其中隔离性又包括四个级别:

  1. READ_UNCOMMITTED:读未提交, 这种隔离级别指的是A事务可以读取到B事务还没有提交的数据,显然这种隔离级别是不安全的,它容易引发不可重复读、脏读和幻读。
  2. READ_COMMITTED:读已提交,这种隔离级别指的是A事务只能读取到B事务已经提交的数据,这种隔离级别比上面一种安全一些,但是只能止脏读。
  3. REPEATABLE_READ:可重复读,虽然名字叫可重复读,但是它的意思是:重复读同一条数据的情况下,能保证读的结果是一致的。不少人被这个名字误解,它的原理大致是A事务在开始后会将数据库中的数据假冻结,也就是说无论B事务对数据作什么样的改变,A事务读到的数据都是事务开始时的样子,这样就做到了无论读多少次数据都是一致的。但是这种情况下还是会有幻读的情况出现
  4. SERIALIZABLE串行化,这种隔离级别也是最高的,所有的事务都必须像单线程一样,一个个执行。它可以防止幻读。

四种隔离级别中,并发编程下:1的性能最高,但是最不安全,4的性能最低,但是最安全,MySQL中的默认隔离级别是REPEATABLE_READ。

查看mySQL8.0的事务隔离级别

/*查看当前会话的事务隔离级别*/
select @@transaction_isolation;
/*查看mysql的事务隔离级别*/
select @@global.transacton_isolation;

修改mysql8.0中的事务隔离级别

/*设置当前会话的隔离级别 */
/*设置read uncommitted级别*/
set session transaction isolation level read uncommitted;
/*设置read committed级别*/
set session transaction isolation level read committed;
/*设置repeatable read级别*/
set session transaction isolation level repeatable read;
/*设置serializable级别*/
set session transaction isolation level serializable;

/*设置mysql全局的隔离级别 */
/*设置read uncommitted级别*/
set global transaction isolation level read uncommitted;
/*设置read committed级别*/
set global transaction isolation level read committed;
/*设置repeatable read级别*/
set global transaction isolation level repeatable read;
/*设置serializable级别*/
set global transaction isolation level serializable;

---------------------------------------------------------------------------------下面是实例演示:-----------------------------------------------------------------------------------------------------------

下面将用实例来演示四种隔离级别以及可能出现的问题:

首先先新增一张Student表, 表中有id,name,score字段,并填入测试字段

数据库事务的隔离级别

1.READ_UNCOMMITTED

 

 

 然后我们打开两个会话,并将两个会话的事务隔离级别都设置为read_uncommitted

数据库事务的隔离级别

数据库事务的隔离级别

我们在left会话中先开启一个事务,然后查询s1的分数,此时可以看到分数是10

数据库事务的隔离级别

 

然后在right会话中再开启一个事务,然后把s1的分数改为99,但是先不要提交,也不要回滚

数据库事务的隔离级别

 

 

 然后我们再去left会话中单独执行查询s1的分数语句,可以看到明明事务还没有提交, 却可以看到被修改成了99。这就是脏读

数据库事务的隔离级别

2.READ_COMMITTED

 还是打开两个窗口模拟两个事务。 然后将两个窗口的事务隔离级别都修改为read_committed,因为修改方式和上面一样就不放图了。

 

 

 然后还是在left中查询s1的成绩

数据库事务的隔离级别

 

然后再次在right中修改为99

数据库事务的隔离级别

 

 

 再次执行在left中执行的话,可以看到还是10,因为我们改变了事务的隔离级别,right没有提交的修改我们在left中看不到,这种隔离级别就防止了脏读的出现

数据库事务的隔离级别

 

 

 然后我们执行right的commit

数据库事务的隔离级别

 

 

 再次在left中查询s1,可以看到成绩变为了99。因为right已经提交了事务,所以可以在left中看到,但是这又出现了left事务中同一条语句查询两次而得到的查询结果不一致的问题,这就是数据的不可重复读问题。

其实我觉得这个名字很容易误导很多人, 要是翻译成 "读取结果不一致" 的话可以更贴近事实

数据库事务的隔离级别

3.REPEATABLE_READ

 可以从这个隔离级别的字面意思上理解“可重复读”,这个可重复读可以解决就可以解决不可重复读的问题。

我们还是先将left和right的隔离级别都设置为repeatable_read

 和之前一样的,还是先在left中开启事务,查询s1

数据库事务的隔离级别

 

 

 然后在right中开启事务,修改为100,最后直接提交

数据库事务的隔离级别

 

 

 然后我们返回到left中查看,可以看到虽然right的事务提交了,但是left中的结果依然是99。这就是repeatable_read这个隔离级别解决了不可重复读的问题(其实换一种更直接的说法就是:repeatable_read这个隔离级别解决了多次读取数据不一致的问题,在一个事务当中,多次读取同一条数据,无论如何都是相同的)

数据库事务的隔离级别

 

 

 但是这种隔离级别还是会有幻读的情况出现,比如说:先在left中开启事务, 查看所有的学习成绩

数据库事务的隔离级别

 

 此时可以看到一共有s1和s2两条数据,然后我们去right中将s2删掉

数据库事务的隔离级别

 

 然后再回到left中查看,还是两条,没有任何问题,因为repeatable_read会将当前事务中的数据进行假冻结

数据库事务的隔离级别

 

 然后这时我们将s2的成绩修改成100,这时可以看到这个update语句的影响行数为0,这时我们再去重新执行select语句可以发现明明是有s2的,但是这条更新语句就是没有效果,就像我们看到的s2是幻觉一样,这就是幻读

数据库事务的隔离级别

 

4.SERIALIZABLE

从字面意思上理解的话是序列化、串行化。 但是这里指的其实是所有的事务必须一个个的按顺序执行。这种隔离级别可以有效的防止以上任意一种错误出现

还是先将left和right的隔离级别都改为serializable

 我们再重现刚刚的场景:先在left开启一个事务,然后查询student

数据库事务的隔离级别

 

然后在right中删除s2,可以看到right就一直是正在处理

数据库事务的隔离级别

 

如果一直等待的话这就会因为超时而无法执行,因为这个隔离级别的所有事务都必须像单线程一样一个个顺序执行,没有办法同时处理,只要left不提交,right就永远没有办法执行。所以right没有办法将s2删除, 自然就不会有幻读的情况出现了。不过正如我们看到的那样,因为隔离级别太高了,导致事务只能按顺序执行,这种的性能是非常差的。所以mysql退而求其次选择了可重复读(也就是多次读取时结果一致)这种隔离策略

数据库事务的隔离级别

 

 最后总结一下:

  ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

  ③ Read committed (读已提交):可避免脏读的发生。

  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

 

 

ps:本文灵感来自b站江南一点雨江南一点雨的个人空间_哔哩哔哩_bilibili,他的数据库事务隔离级别的视频讲的特别清楚,推荐大家去看看

脚本宝典总结

以上是脚本宝典为你收集整理的数据库事务的隔离级别全部内容,希望文章能够帮你解决数据库事务的隔离级别所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。