侧边栏壁纸
博主头像
与晚风述往事博主等级

万般皆下品,唯有读书高。

  • 累计撰写 149 篇文章
  • 累计创建 29 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

Oracle 事务隔离级别

与晚风述往事
2022-04-02 / 0 评论 / 1 点赞 / 343 阅读 / 1,628 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-04-02,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

SQL标准隔离级别

在聊Oracle事务之前,首先先简单介绍下SQL标准。

SQL标准是ANSI定义的一套标准化的语法。它根据并发执行的事务之间出现的问题定义了四个级别的事务隔离,分别是:

  • 读未提交(Read uncommitted)
  • 读已提交(Read committed)
  • 可重复读(Repeatable read)
  • 序列化(Serializable)

这四个隔离级别与之关联的问题有三种:

  • 脏读
  • 不可重复读
  • 幻读

接下来简单介绍下这三个问题是怎么产生的?

脏读,就是一个事务读取已由另一个尚未提交的事务写入的数据。简单来说,就是会话A执行了一个语句,将表中的数据进行了修改,此时还没有提交,会话B查看该表时,看到的数据是已经被会话A修改的数据,这种现象被称为“脏读”。

不可重复读,就是一个事务重新读取它之前读取的数据,发现另一个已提交的事务修改或删除了数据。简单来说,就是会话A第一次执行了一个查询语句,看到表A的数据是“张三”,再次执行该查询时,发现表A的数据是“李四”,这种现象被称为“不可重复读”。

幻读,就是事务重新运行返回一组满足查询条件的行的查询语句,发现另一个已提交的事务插入了满足条件的新记录。简单来说,就是事务在第一次查询时,有30条记录,但是在第二次查询时,同样的条件有35条记录,这种现象被称为“幻读”。

根据隔离级别和带来的问题可以将其划分为如下表格:

隔离级别 脏读 不可重复读 幻读
读未提交(Read uncommitted) 可能出现 可能出现 可能出现
读已提交(Read committed) 不可能出现 可能出现 可能出现
可重复读(Repeatable read) 不可能出现 不可能出现 可能出现
序列化(Serializable) 不可能出现 不可能出现 不可能出现

以上就是SQL标准定义的隔离级别以及它们可能引起的数据问题。

Oracle事务隔离级别

在Oracle数据库中,完全兼容ANSI的标准SQL语句,但它的隔离级别与SQL标准提出的又略有不同。Oracle数据库中提供了三种事务的隔离级别:

  • 读提交(Read Committed)
  • 序列化(Serializable)
  • 只读隔离级别(Read-Only)

这三种隔离级别中,前两种跟SQL标准提出的基本一致,但第三种是Oracle自己提供的隔离级别。在Oracle数据库中,默认隔离级别是读提交(Read Committed)。

读提交

在读提交隔离级别中,事务中的每个查询只能看到查询开始之前已提交的数据,而不是事务开始时的。例如事务A更新了某个表的数据,此时事务B查询该表只能看到事务A更改之前的数据,这也就意味着读提交隔离级别中,是可能会发生“不可重复读”和“幻读”的。

Oracle会在事务尝试修改由未提交的并发事务更新的行时,未提交的事务就被为阻塞事务。在此期间,当前的事务会一直等待阻塞的事务结束并释放锁。在这个等待的阶段,当前事务就可能会出现以下情况:

  • 阻塞事务回滚,则等待事务继续更改之前被阻塞事务锁定的行,就像是阻塞事务不存在一样。
  • 阻塞事务提交并释放其锁的话,则等待的事务继续对其新更新的行进行更新。

序列化

在序列化隔离级别中,事务只能看到在事务开始时提交的更改(注意,不是查询)以及事务本身所做的更改。例如,事务A在对某行执行更新操作,事务B在事务A执行后也对该行进行了更新(此时事务A还没提交),事务A在提交后,事务B再提交会报错ORA-08177。因为事务A已对该行数据进行了修改,事务B没法修改该行数据,需要重新开启事务才能继续修改。

从上述概念上来看,序列化隔离级别更适合在下面的场景中:

  • 大型数据库和仅更新几行的小事务
  • 并发事务修改相同行的机率比较低
  • 较长时间运行的事务主要是只读的情况

只读隔离级别

在Oracle数据库中还提供了一种特殊的隔离级别,叫做只读隔离级别。它与序列化隔离级别很类似,唯一不同的地方就是只读事务不允许在事务中修改数据(除SYS用户外)。从这里也就可以看出,只读隔离级别基本上不会出现ORA-08177错误。

1

评论区