Oracle的数据一致性机制原理

一、前言

在单用户环境下,在操作数据库是不需要考虑其他用户会修改同一个数据。但是在多用户的情况下,多个事务可能会修改同一个数据,最终会得到错误的数据结果。

Oracle数据库是通过 multiversion consistency model(多版本数据一致性模型)、还有不同类型的锁、事务隔离保证数据的一致性。

通过这种方式,数据库可以向多个并发用户提供在某一个时间点所对应的数据库数据。由于不同版本的数据块可以同时存在,事务可以查询所需时间点已经提交的数据版本,并返回对应时间点已提交的数据查询结果。(数据块的头部存储了历史事务信息)

提问:什么是数据一致性呢?

在数据库中,数据一致性是指在多个并发事务同时访问数据库时,确保读取操作的结果对于所有事务都是一致的。

这意味着当一个事务正在读取数据时,如果其他事务正在对相同的数据进行修改或写入操作,读取操作不应该看到未完成的或部分更改的数据。相反,读取操作应该看到已经提交的、完整的数据,以确保事务之间的数据一致性。

二、数据读一致性

数据的读一致性分为两个层面,一个是语句级别的读一致性,另外一个是事务级别的读一致性。

2.1、语句级别读一致性(Statement-Level Read Consistency)

Oracle数据库强制使用语句级别的读一致性,这样保证每次返回的数据是在这个时间节点之前已经提交的数据。

在这里插入图片描述
当进行一次查询时,发生在 SCN 10023(SCN是Oracle数据库的一种顺序标识,代表事务先后),只会看到10023之前已经提交的数据。在图中有两个大于SCN10023的数据块,是SCN1024,这时 Oracle数据库会将这两个数据块拷贝到一个缓冲区中,然后根据undo segment(撤销段)中的数据重新构建这两个数据块(CR,consistent read clones)在1024前已经提交的数据,最后正确的检索就是SCN100021->SCN100021->SCN10006->SCN10008->SCN10021->SCN10011->SCN10021,过这种机制每次查询的时候查询到的都是事务已经提交的数据,防止了脏读。

提问:那什么是SCN呢?

SCN的全称是System Change Number,它在数据库中充当时钟的角色,是数据库内部使用的一个逻辑数据,Oracle数据库可以根据它的大小来判断事务发生的先后顺序。Oracle数据库是在SGA(Sytem Global Area)中完成SCN增量操作。当事务修改数据时,数据库会将新的SCN保存到与事务相对应的撤销段中(undo segment)中。

提问:即使有了SCN机制,数据库能够知道事务的先后顺序,那数据库是怎么知道事务提交了还是没有提交?

每一个数据库块(block,Oracle数据库底层逻辑存储最小单元),都有一个数据块头(block header),里面包含了在数据库块上进行的事务活动(事务执行历史),里面记录了事务的状态(活跃 Active、提交 Commit、回滚 RollBack)。

2.2、事务级别的读一致性(Transaction-Level Read Consistency)

Oracle数据同样也可以对一个事务中的多条查询语句提供读一致性。在事务中的每条语句看到的都是同一节点(同一SCN)的已经提交的数据。

2.3、读一致性的数据存储

提问:Oracle数据库是如何给每个不同SCN对应的事务看到之前已经提交的数据呢?这些数据又是放到那里呢?

要管理多版本读取一致性模型(multiversion read consistency model),数据库必须在同时查询和更新表时创建一组读取一致性数据。

这里就涉及到了撤销段,撤销段(undo segment)是数据库的一个逻辑结构,用于管理extents(区),而 extents 是由多个数据库块(block)组成。

每当用户修改数据时,Oracle 数据库都会产生一个撤销数据实体(undo entries),之后会将这个实体写入到撤销段(undo segment)中。撤销段中包含已提交事务或者未提交事务所作更改之前数据库中的旧数据,

通过这种方式,同一个数据,在不同时间节点的不同版本数据可以存在于数据库中。这样数据库可以提供不同时间节点,不同版本的数据库快照视图,来保证读一致性。

2.4、锁机制

Oracle数据的某一条事务在修改数据时,其他事务不能在进行修改,实现这种操作就要使用到锁机制。

锁我的理解是它是一种机制,一种用于防止破坏性交互行为的机制,破坏性行为就是指并发修改某一个数据,修改后的结果是错误的,通过锁这种机制来避免错误的修改结果,保证数据库数据的一致性。

锁大致可以分为两类,一种是排他锁,另外一种是共享锁。多个资源在竞争锁时,只有一个资源能够获取到排他锁,多个资源可以获取到共享锁。只有当修改数据时,数据才会被锁定,正常情况下是锁定一行数据,而不是整张数据库表。

三、事务隔离级别

Oracle数据库提供三种事务隔离级别分别是RC(read committed)、Serializable、read-only。

在这里插入图片描述
3.1、RC隔离级别

RC隔离级别是Oracle数据库默认的隔离级别,在RC隔离级别下可以保证每次查询到的数据都是事务已经提交的数据,不会读取到事务未提交的数据,保证数据的一致性。也就说当一个查询正在查询一个表中id为2的数据时,此时另外一个事务把该数据修改了,但是查询出的结果是修改之前的结果,不会查询到事务未提交的结果。

在RC隔离级别下,可能会出现更新丢失的问题。这是一个很诡异的现象。举个例子说一下:

假设某公司要给小张涨工资1k,现在有两个财务操作员A和B,它们进行了以下操作:

1.操作员A查询出了小张现有的工资,选择了薪水修改,并输入了要提薪的1000数据,但此时有事,临时走开了,没有提交(事务未提交)。

2.操作员B查询出小张现有的工资,选择了薪水修改,并输入了要提薪的1000数据,然后提交了修改。

3.操作员A忙完事情回来了,然后提交了修改。

小张高兴坏了,自己涨了两千的工资。

在这个例子中操作员A没有提交,但是在提交的时候要重新查询一下看一下薪水有没有被修改。这样不会造成操作员B的修改丢失。

比如可以通过乐观锁的形式,给表上添加版本列进行解决,版本列可以是日期,一个递增的版本数字等。这是一种比较好的方式,当然也存在其他方式。

3.2、Serializable隔离级别

Serializable隔离级别是Oracle数据库最高级的事务隔离级别,在这个级别下,数据库确保事务之间的操作不会相互干扰(行级锁定、多版本并发控制等),从而保证了数据的一致性和完整性。

在序列化事务隔离级别下,事务只能看到在事务开始时做的更改以及事务本身所做的更改。如果某个事务开始后,其他事务已经提交了对相同数据的修改,那么这个事务就会被视为尝试修改已经被其他事务更改的数据,此时Oracle数据库会抛出ORA-08177: Cannot serialize access for this transaction异常。

3.3、Read-Only隔离级别

read-only事务隔离级别,是一个简单粗暴的事务隔离级别,它只允许事务进行读取数据,不允许修改数据,但是当用户是sys用户时将允许进行数据修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/247585.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AWS攻略——使用中转网关(Transit Gateway)连接同区域(Region)VPC

文章目录 环境准备创建VPC 配置中转网关给每个VPC创建Transit Gateway专属挂载子网创建中转网关创建中转网关挂载修改VPC的路由 验证创建业务Private子网创建可被外网访问的环境测试子网连通性Public子网到Private子网Private子网到Private子网 知识点参考资料 在《AWS攻略——…

基于SSM的老年公寓信息管理的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

pip命令详解

pip命令介绍 pip是由Ian Bicking在2008年提出的,他将pyinstall重命名为pip。名称pip是首字母缩写词,全称为“Package Installer for Python”。自Python3的3.4版本以及Python2的2.7.9版本开始,pip被直接包括在Python的安装包内,成…

树_二叉树所有路劲

//给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。 // // 叶子节点 是指没有子节点的节点。 // // 示例 1: // // //输入:root [1,2,3,null,5] //输出:["1->2->5&quo…

Liunx高级程序设计-Shell -1

引入 完成以下任务 : 判断用户家目录下(~ )下面有没有一个叫 test 的文件夹 如果没有,提示按 y 创建并进入此文件夹,按 n 退出 如果有,直接进入,提示请输入一个字符串,并按此字符串创建…

14、策略模式(Strategy Pattern)

策略模式(Strategy Pattern)为同一个行为定义了不同的策略,并为每种策略都实现了不同的方法。在用户使用的时候,系统根据不同的策略自动切换不同的方法来实现策略的改变。同一个策略下的不同方法是对同一功能的不同实现&#xff0…

分布式搜索引擎elasticsearch(一)

5.1 初始elasticsearch elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。 elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。 5.1.1正向索引 5.1.2elasticsearch采用倒排索引: 文档(document):每条数据就是一个…

【深度学习】回归模型相关重要知识点总结

回归分析为许多机器学习算法提供了坚实的基础。在这篇文章中,我们将总结 10 个重要的回归问题和5个重要的回归问题的评价指标。 一、线性回归的假设是什么 线性回归有四个假设: 线性:自变量(x)和因变量(y&…

Elasticsearch:评估 RAG - 指标之旅

作者:Quentin Herreros,Thomas Veasey,Thanos Papaoikonomou 2020年,Meta发表了一篇题为 “知识密集型NLP任务的检索增强生成” 的论文。 本文介绍了一种通过利用外部数据库将语言模型 (LLM) 知识扩展到初始训练数据之外的方法。 …

SpringBoot药品进销存管理系统(诊所管理系统)(乡村药店管理系统)

SSM毕设分享 SpringBoot药品进销存管理系统(诊所管理系统)(乡村药店管理系统) 1 项目简介 Hi,各位同学好,这里是郑师兄! 今天向大家分享一个毕业设计项目作品【SpringBoot药品进销存管理系统(诊所管理系统)(乡村药店管理系统)】 师兄根据实…

简单了解传输层协议之TCP和UDP

目录 一、什么是端口号? 二、TCP协议 2.1 TCP报文格式 2.2 三次握手 2.3 四次挥手 2.4 窗口流量控制 三、UDP协议 3.1 UDP报文格式 3.4 传输过程 一、什么是端口号? 我们自己的一台电脑上有时可能会同时运行多个进程软件来进行上网。那么当网络上的服务器响应我们电…

Redis持久化及常见问题解决

持久化缓存雪崩缓存穿透缓存击穿缓存预热 持久化 Redis的储存形式:一份在内存、一份在磁盘。内存的是最新的;磁盘里的会隔一段时间更新。 Redis持久化方式: RDB:快照方式;将某⼀个时刻的内存数据,以⼆进制的⽅式写⼊…