隔离限制情景简介

本文深入探讨了数据库事务的四种隔离级别:读未提交、读已提交、可重复读和串行化。通过实例解析了脏读、不可重复读和幻读的现象,并提供了相应的解决方案。强调了在不同场景下选择合适隔离级别的重要性,以避免数据不一致性和并发问题。
摘要由CSDN通过智能技术生成

隔离限制

隔离级别

一.read uncommitted

此级别脏读的问题复现:
设置当前数据库的隔离级别为 read uncommitted
SELECT @@tx_isolation;
set GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
重启连接数据库的客户端后,分别开启两个查询窗口(自己搞个表用于测试)
-------------
START TRANSACTION;
SELECT * FROM test02;
ROLLBACK;
COMMIT;
------------
START TRANSACTION;
UPDATE test02 SET age=age-1 WHERE id=2;
UPDATE test02 SET age=age+1 WHERE id=5;
ROLLBACK;
COMMIT;
同时开启事务,先执行修改的操作,然后在进行查看,此时读取的数据是事务中刚刚修改后,但没有提交的数据(即还是存在于内存的数据),我们可以运行rollback;取消刚才的更改,这样第一次读的消息就是假消息了,这种现象我们叫做读脏.
---
解决办法:更改隔离限制 set GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
--
设置为read committed 模式后,同时开启事务,修改数据后,另一端进行查询,查询的结果是没有更新前的数据,直到提交后,才读取到更新后的数据.
--
把脏读问题解决后,这种模式依然会发生其他现象,不可重复度和幻读,不要着急,一步一步来.

二.read committed

接着上面的说,我们把隔离限制设置为read committed后,就把脏读的现象给解决了,然后开始理解不可重复读现象.
这种现象并不是会出错,只是应用在不同的场景.
-------
我先说一个场景:假如一个公司每天需要整理12点整的数据库数据,假设处理数据需要10分钟,那么在12:00-12:10查询数据期间,如果有数据更新并提交了,(根据第一种现象的解决分析)那么整理的数据就不是12点整的数据了,而是含有12点之后的数据了,但是公司只需要12点之前的数据,这样查询的结果不就和预期的不一致了吗,我们把这种现象叫做不可重复读现象.
那么改如何解决呢?不慌,mysql有办法.
-------------
START TRANSACTION;
SELECT * FROM test02;
ROLLBACK;
COMMIT;
------------
START TRANSACTION;
UPDATE test02 SET age=age-1 WHERE id=2;
UPDATE test02 SET age=age+1 WHERE id=5;
ROLLBACK;
COMMIT;
-----------
代码依然如此,解决这种现象只需要把隔离限制模式改为repeatable read
set global transaction isolation level repeatable read;
我这里的数据很少,所以不会出现查询10分钟的情况,所以我可以执行两次查询来区分.同时开启事务,进行第一次查询操作,然后修改数据并提交事务,再次执行查询操作,发现查询结果并不是修改后的数据了,直到我提交该事务,我再次查询,发现才查询到更新后的结果了,这样如果公司不想出现不可重读的问题就解决了.
---------
注意,不可重复度并不是错误现象,它只是出现在特定的情况下不合适罢了.

三.repeatable read

repeatale read已经解决了脏读和不可重复读的现象了,还有最后一个现象--脏读
脏读就是两个或多个事务之间出现的不协调现象.两个事务同时进行,第一个事务插入一条数据提交,然后第二条数据先查看表(由于是可重复读,查询的数据是第一个事务插入之前的数据),同时插入相同的数据,发现报错,说插入的数据重复,这种奇怪的现象就叫做幻读.
----
START TRANSACTION;
insert into test02 values(100,'艾因司谭',99);
ROLLBACK;
COMMIT;
-------
START TRANSACTION;
select * from test02;
insert into test02 values(100,'艾因司谭',99);
ROLLBACK;
COMMIT;
---
先同时开启事务,第一个事务先插入并提交成功,第二个事务查询发现并没有id为100的人,添加竟然报错发现已经有这个人了,惊不惊喜!!
解决办法:终极大招 set global transaction isolation level serializable;
这样,脏读,不可重复读,幻读的问题都能解决了.

四.Serializable

serializable可以解决上面的一系列问题,那么是否意味着所有情况都用这个方法解决就行了?
当然不是,这四个隔离限制从上到下逐渐提高,效率逐步降低,所以说不一定是功能最完善的是最好的,要根据合适的场景选择合适的隔离限制.

最后做一下总结

隔离级别名称会引发的问题
read uncommitted读未提交脏读,不可重复读,幻读
read committed读已提交不可重复读,幻读
repeatable read可重复读幻读
serializable串行化
问题现象
脏读在一个事务处理过程中读取到了另一个事务为提交的数据
不可重复读在一个事务处理过程中读取到另一个事务提交的数据,导致查询结果不是想要的
幻读查询数据不存在,准备插入数据却发现数据已经存在了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值