浅谈mysql数据库中的隔离级别与事物介绍

前言:
READ UNCOMMITED(未提交读)

在RERAD UNCOMMITED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也成为脏读(Dirty Read)。这个级别会导致很多问题,从性能上说READ UNCOMMITED 不会比其他的级别好太多,但缺乏其他级别的好多好处,除非有非常必要的理由,在实际的应用中一般很少使用READ UNCOMMITED.

READ COMMITED (提交读)

大多数数据库系统的默认隔离级别都是READ COMMITED (但是MYSQL不是)。READ COMMITED 满足前面提到的隔离性的简单定义:一个事务开始时,只能看到已经提交的事务所做的修改。换句话说,一个事务从开始到提交之前,所做的任何修改对其他事务都 是不可见的。这个级别有时候也叫做不可重复的(nonerepeatable read),因为两次执行同样的查询,可能会得到不一样的结果。

REPEATABLE READ (可重复读)

REPEATABLE READ (可重复读) 解决了脏读问题。该级别保证了在同一个事务中多次读取同样的记录的结果是一致的。但是,理论上,可重复读隔离级别还是无法解决另一个幻读 (PhantomRead)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读 取该范围的记录时,会产生幻行(Phantom Row)。InnoDB和XtraDB 存储引擎通过多版并发控制(MVCC ,Multivesion Concurrency Control )解决了幻读问题。

可重复读是Mysql 默认的事务隔离级别。

SERIALIZABLE(可串行化)

SERIALIZABLE是最高的隔离级别。它通过强制事务串行,避免了前面说的幻读问题。简单的来说,SERIALIZABLE会在读的每一行数据上 都加上锁,所以可能导致大量的超时和锁征用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况,才可考 虑用该级别。

隔离级别    脏读可能性    不可重复读可能性    幻读可能性    加锁读

READ UNCOMMITED  YES   YES          YES       NO

READ COMMITED    NO   YES          YES       NO

REPEATABLE READ   NO   NO           YES       NO

SERIALIZABLE      NO    NO           NO       YES
事物:事物是指一组原子性的SQL查询。(如:银行转账:a要转账给b100,在数据库中至少三步 1.a的账户查询余额大于100,2.a账户减少100,3.b的账户要增加100这样这个事物才算真的完成,这里的几条sql语句应该一起完成或者失败,失败就会发生回滚,成功则提交事务。)。

隔离:隔离的产生主要是在并发情况下读取数据可能出现脏读,不可重复读和幻读的情况。因为并发的存在,可能会出现同一时间,多个人对一个数据或者表查询或者修改。

事务的原子性,隔离性,一致性和持久性。
原子性:对于一个事务来说,不可能只执行其中的一部分操作。

一致性:数据库总是从一个一致性状态转换到另一个一致性状态。在转账表示中则是总体的钱是不变的,如数据库中总共有1000元,则事务完成后还是1000元,不同的是其中的几个账户的钱变了。

隔离性:一般来说,一个事务做的修改提交前,对于其他事务不可见。比如上面转账例子中,若a账户原来有200元,执行到第二步a账户减少100,此时还没有把事务执行提交,那么当另外一个事务查询a账户余额时仍然为200。(这只是一般情况,如果真的这样我想不会出现脏读了)

持久性:持久性是个模糊的概念,它是指:一旦事务提交,它的修改就会永久保存到数据库中,系统崩溃也不会丢失。这个我觉得就不是我们需要考虑的了,天灾人祸,洪水旱涝,听天由命。

数据库并发访问出现的问题:
脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。如:转账问题,到了第三步时,新来的事务访问b余额是100,但是发现b账户出了问题,于是回滚了,b余额又是200了,导致错误。

不可重复读:比如现在有一个事务要读取两次a的余额,第一次读取余额在转账之前,是200,但是第二次读取时,a已经完成转账,读取为100,这就是不可重复读。

幻读:幻读和不可重复读差不多,不过不可重复读针对的是数据不一样,而幻读针对读取时的数据量不一样,比如查询余额为200的人,第一次查询为n个(此时包括a),第二次查询时a转完账了,此时查询结果为(n-1)。

第一类丢失更新,第二类丢失更新。这个直接看的网上,第一类丢失更新中事务撤销不是特别理解,但是第二类就相当于一次提交覆盖另一次提交吧。

read uncommitted(未提交读):事务中的修改,即使没有提交对其他事务也是可见的。(不满足隔离性)。

read commited(提交读):解决了脏读。大多数数据库默认隔离级别都是这个(但MySQL不是)。它满足隔离性的简单定义:一个事务开始时只能看见已经提交的事务所做的修改(好拗口,慢慢理解)。

repeatable read(可重复读):解决了脏读的问题和不可重复读问题。保证了同一个事务多次提取同样数据结果一样。但理论上为解决幻读问题。

serializable(可串行化):隔离级别最高,强制事务串行化,相当于没有并发。

猜你喜欢

转载自blog.csdn.net/qq_38413862/article/details/88897080