暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

怎么理解SQL的四个事务隔离级别?

SQL数据库运维 2021-11-16
1131

点击蓝色字关注“SQL数据库运维”

在关系型数据库中,事务的隔离性分为四个隔离级别,在解读这四个级别前先了解一下几个数据读取的概念。
高并发情况下,事务可能出现的几种情况:脏读、幻读、不可重复读

1、脏读

出现原因:一个事务读取到了缓存中另一个事务未提交的脏数据。

说明:当事务B对data进行了修改但是未提交事务,此时事务A对data进行读取,并使用事务B修改的数据做业务处理。

2、幻读(虚读

出现原因:一个事务在读取数据时,另一个事务插入了数据,导致上个事务第二次读取数据时,数据不一致。

说明:data 表有一条数据,事务A对data进行读取, 事务B对data进行数据新增 ,此时事务A读取只有一条数据,而最后实际data是有两条数据,就好象发生了幻觉一样情况成为幻读。

3、不可重复读

出现原因:读取数据的同时可以进行修改;

说明:事务A、事务B同时对data进行访问,事务A对data进行读取,事务B对data进行修改,当事务A第一次对data进行读取完后事务B提交,此时当事务A第二次读取该数据时的数据就与第一次读取的数据不同,这种情况称为不可重复读。

为了避免上述事务并发问题的出现,在标准的 SQL 规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。这四种事务的隔离级别如下。

1)Read Uncommitted(读未提交)

一个事务在执行过程中,既可以访问其他事务未提交的新插入的数据,又可以访问未提交的修改数据。如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。此隔离级别可防止丢失更新。

2)Read Committed(读已提交)

一个事务在执行过程中,既可以访问其他事务成功提交的新插入的数据,又可以访问成功修改的数据。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。也就是说,在事务处理期间,如果其他事务修改了相应的表,那么同一事务的多个SELECT语句可能返回不同的结果。此隔离级别可有效防止脏读。但会出现不可重复读。

3)Repeatable Read(可重复读取)

一个事务在执行过程中,可以访问其他事务成功提交的新插入的数据,但不可以访问成功修改的数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。也就是说,如果用户在另外一个事务中执行同条SELECT语句数次,结果总是相同的。(因为正在执行的事务所产生的数据变化不能被外部看到)此隔离级别可有效防止不可重复读和脏读。

4)Serializable(可串行化)

提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。此隔离级别可有效防止脏读、不可重复读和幻读。但这个级别可能导致大量的超时现象和锁竞争,在实际应用中很少使用。

总结:

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然一般来说,事务的隔离级别越高,越能保证数据库的完整性和一致性,但相对来说,隔离级别越高,对并发性能的影响也越大。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况而定。通常将数据库的隔离级别设置为 Read Committed,即读已提交数据,它能够避免脏读取,而且具有较好的并发性能尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁乐观锁来控制。
在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。在Oracle数据库中,只支持Serializeble(串行化)级别和Read committed(读已提交)这两种级别,默认的隔离级别为Read Committed(读已提交)

点击关注“SQL数据库运维”,后台回复关键字:进群,带你进入高手如云的技术交流群。后台回复关键字:SQL,获取学习资料。

文章转载自SQL数据库运维,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论