- 浏览: 4406978 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (634)
- Oracle日常管理 (142)
- Oracle体系架构 (45)
- Oracle Tuning (52)
- Oracle故障诊断 (35)
- RAC/DG/OGG (64)
- Oracle11g New Features (48)
- DataWarehouse (15)
- SQL, PL/SQL (14)
- DB2日常管理 (9)
- Weblogic (11)
- Shell (19)
- AIX (12)
- Linux/Unix高可用性 (11)
- Linux/Unix日常管理 (66)
- Linux桌面应用 (37)
- Windows (2)
- 生活和工作 (13)
- 私人记事 (0)
- Python (9)
- CBO (15)
- Cognos (2)
- ORACLE 12c New Feature (2)
- PL/SQL (2)
- SQL (1)
- C++ (2)
- Hadoop大数据 (5)
- 机器学习 (3)
- 非技术 (1)
最新评论
-
di1984HIT:
xuexilee!!!
Oracle 11g R2 RAC高可用连接特性 – SCAN详解 -
aneyes123:
谢谢非常有用那
PL/SQL的存储过程和函数(原创) -
jcjcjc:
写的很详细
Oracle中Hint深入理解(原创) -
di1984HIT:
学习了,学习了
Linux NTP配置详解 (Network Time Protocol) -
avalonzst:
大写的赞..
AIX内存概述(原创)
多用户环境下的数据并发访问及数据一致性简介
在只有单一用户的数据库中,用户可以任意修改数据,而无需考虑同时有其他用户正在修改相同的数据。但在一个多用户数据库中,多个并发事务中包含的语句可能 会修改相同的数据。数据库中并发执行的事务最终应产生有意义且具备一致性的结果。因此在多用户数据库中,对数据并发访问(data concurrency)及数据一致性(data consistency)进行控制是两项极为重要的工作。
1、数据并发访问指多用户同时访问相同的数据。
2、数据一致性指系统中每个用户都能够取得具备一致性的数据,同时还能够看到自己或其他用户所提交的事务对数据的修改。
为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被称为串行化处理(serializability)的事务隔离模型(transaction isolation model)。当所有事务都采取串行化的模式执行时,我们可以认为同一时间只有一个事务在运行(串行的),而非并发的。
以串行化模式对事务进行隔离的效果很好,但在此种模式下应用程序的效率将大大降低。将并行执行的事务完全隔离意味着即便当前只存在一个对表进行查询(query)的事务,其他事务也不能再对此表进行插入(insert)操作了。总之,为了满足实际要求,我们需要在事务的隔离程度与应用的性能之间找出一个平衡点。
Oracle 支持两种事务隔离级别(isolation level),使应用程序开发者在对事务进行控制时,既能保证数据的一致性,又能获得良好的性能。
需要防止的现象和事务隔离级别
ANSI/ISO SQL 标准(SQL92)定义了四种事务隔离级别(transaction isolation level),这四种隔离级别所能提供的事务处理能力各不相同。这些事务隔离级别是针对三种现象定义的,在并发事务执行时,需要阻止这三种现象 中的一种或多种发生。
三种需要阻止的现象(preventable phenomena)是:
1、脏读取(dirty read):一个事务读取了被其他事务写入但还未提交的数据。
2、不可重复读取(nonrepeatable read):一个事务再次读取其之前曾经读取过的数据时,发现数据已被其他已提交的事务修改或删除。
3、不存在读取(phantom read):事务按照之前的条件重新查询时,返回的结果集中包含其他已提交事务插入的满足条件的新数据。
SQL92 标准中定义了四个隔离级别,在各隔离级别中,允许发生上述三种需要阻止的现象中的一种或多种。详情见下表
现象 | 脏读取 | 不可重复读取 | 不存在读取 |
隔离级别 | |||
|
|||
未提交读取(read uncommitted) |
允许 | 允许 | 允许 |
已提交读取(read committed) |
不允许 |
允许 | 允许 |
可重复读取(repeatable read) |
不允许 |
不允许 | 允许 |
串行化(rerializable) |
不允许 |
不允许 | 不允许 |
Oracle 支持三种事务隔离级别:已提交读取,串行化,以及 SQL92 中没有包含的只读模式(read-only mode)。已提交读取是 Oracle 默认使用的事务隔离级别。
Oracle 如何管理数据并发访问及数据一致性
Oracle 利用多版本一致性模型(multiversion consistency model),各种类型的锁及事务来管理多用户系统中的数据一致性(data consistency)。
多版本并发访问控制
Oracle 能够自动地实现一个查询的读一致性,即一个查询所获得的数据来自同一时间点(single point in time)(这也被称为语句级读一致性(statement-level read consistency))。Oracle 还能令一个事务内的所有查询都具备读一致性(即事务级读一致性(transaction-level read consistency))。
Oracle 利用回滚段中的信息生成一个能保证一致性的数据视图。回滚段内保存了未提交或最近提交的事务中所修改数据的原值。下图展示了 Oracle 如何利用回滚段实现语句级的读一致性。
在查询开始执行时,将记录当前的系统变化编号(system change number,SCN)。在 图 中,记录的系统变化编号为 10023。当查询进行扫描时,只会使用有效的(observed)数据块。如果某个数据块内的数据被修改过(即数据块的 SCN 晚于查询开始执行时记录的 SCN),Oracle 将使用回滚段中的信息重建此数据块,并以重建的数据块替代被修改的数据块供查询使用。因此,查询的结果集只包含查询开始执行时就已经提交的数据。在查询执行时,其他事务修改的数据对此查询来说是无效的,这保证了每个查询都能得到满足一致性的数据。
语句级读一致性
Oracle 强制实现语句级读一致性(statement-level read consistency)。这保证了单一查询的结果集来自一个时间点——即查询开始执行的时间。因此,一个查询的结果集永远不会包含脏数据及此查询执行时 其他事务提交的数据。在一个查询执行期间,只有在查询执行前提交的数据对此查询才是可见的。查询无法看到其开始执行后提交的数据。
任何一个查询都能得到满足一致性的结果集,这保证了用户无需额外操作就能确保数据一致性。 SELECT ,使用子查询的 INSERT ,及包含显式或隐式查询的 UPDATE 或 DELETE 语句,都能够保证数据一致性。上述语句通过一个查询(query)来得到她们所需的满足一致性的结果集(分别使用 SELECT,INSERT,UPDATE 或 DELETE 语句)。
SELECT 语句是一个显式地查询,且其中可以包含嵌套查询(nested query)或连接操作(join operation)。 INSERT 语句中也能够使用嵌套查询。 UPDATE 及 DELETE 语句能够利用 WHERE 子句或子查询进行限制,只操作数据表内的部分数据行。
INSERT , UPDATE ,及 DELETE 语句中包含的查询能够获得一致性的结果集。这些查询无法看到其所在 DML 语句对数据的修改。换句话说,这些查询只能看到其所在 DML 语句开始之前的数据。
TIPS:如果 SELECT 列表中存在 PL/SQL 函数,那么函数中包含的 SQL 语句将遵从其自身的语句级读一致性,而非其所在 SQL 的读一致性。例如, SELECT 语句中的某个函数访问的表可能会在语句执行时被其他事务修改并提交。此函数每次执行时都将建立一个新的一致性视图(snapshot)。
事务一致性读
Oracle 还能够实现事务级读一致性(transaction-level read consistency)。当一个事务运行在串行化模式(serializable mode)下时,则事务内所有数据访问均反映的是事务开始时的数据状态。即事务内的所有查询对某个时间点来说具备一致性,但是运行在串行化模式下的事务能够看到事务自身对数据所作的修改。事务级的读一致性能够保证可重复读取并可阻止出现不存在读取。
RAC环境下的读一致性
RAC 系统采用缓存对缓存(cache-to-cache)的数据块传输机制(此技术被称为 Cache Fusion)在实例间传输满足读一致性(read-consistent)的数据块镜像。RAC 系统通过高速度低延迟的内部连接(interconnect)实现上述数据传输,从而满足实例之间对数据块的请求。
Oracle 事务隔离级别
Oracle 支持以下三种事务隔离级别(transaction isolation level)。
隔离级别 | 描述 |
|
|
已提交读取 |
Oracle
默认使用的事务隔离级别。事务内执行的查询只能看到查询执行前(而非事务开始前)就已经提交的数据。Oracle
的查询永远不会读取脏数据(未提交的数据)。 Oracle 不会阻止一个事务修改另一事务中的查询正在访问的数据,因此在一个事务内的两个查询的执行间歇期间,数据有可能被其他事务修改。举例来说,如果一个事务内同一查询执行两次,可能会遇到不可重复读取或不存在读取的现象。 |
串行化 |
串行化隔离的事务只能看到事务执行前就已经提交的数据,以及事务内
INSERT
,
UPDATE
,及
DELETE
语句对数据的修改。串行化隔离的事务不会出现不可重复读取或不存在读取的现象。
|
只读模式 | 只读事务只能看到事务执行前就已经提交的数据,且事务中不能执行 INSERT , UPDATE ,及 DELETE 语句。 |
应用程序的设计开发者及数据库管理员可以依据应用程序的需求及系统负载(workload)而为不同的事务选择不同的隔离级别(isolation level)。用户可以在事务开始时使用以下语句设定事务的隔离级别:
已提交读模式:SET TRANSACTION ISOLATION LEVEL=READ COMMITTED;
串行模式:SET TRANSACTION ISOLATION LEVEL= SERIALIZABLE;
只读模式:SET TRANSACTION= READ ONLY;
(经笔者实验以上命令在非sysdba用户下可以成功执行,sysdba下不能执行,待验证正确性)
如果在每个事务开始时都使用
SET TRANSACTION
语句,将加重网络及处理器的负担。用户可以使用
ALTER SESSION
语句
改变一个会话所有内事务的默认隔离级别:
1、ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;
2、ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;
(无法设置会话级别的只读隔离模式)
已提交读取隔离
Oracle 默认使用的隔离级别(isolation level)是已提交读取(read committed)隔离。这种程度的隔离适合在事务发生冲突的可能性较小的系统中使用。在这种隔离级别下,Oracle 能够保证事务内每个查询在执行期间都拥有一个唯一的数据视图,因此事务可能出现不可重复读取或不存在读取的现象,但此时系统的数据处理能力较高。
串行化隔离
符合以下特性的系统适合采用串行化隔离(serializable isolation):
1、数据量大,但事务短小,只会更新较少数据行的数据库
2、两个并发事务修改相同数据的概率较小
3、运行时间相对较长的事务只执行只读操作
在串行化隔离下,并发事务对数据库进行修改时只能顺序执行。具体来说,在串行化隔离下,Oracle 在允许一个采用串行化隔离的事务修改某些数据行时,需要判断在此事务开始执行之前,其他所有事务对这些数据行的修改已经被提交。
为了实现上述判断,Oracle 在数据块内存储了相关的控制信息,用于记录此块内数据行中所包含的数据是已提交或未提交的。即数据块内记录了近期对本数据块内数据行进行了修改的所有事务及事务的状态。在一个数据块内能够保留多少这样的记录是由 CREATE TABLE 或 ALTER TABLE 语句中的 INITRANS 参数设定的。
有些情况下,Oracle 无法获得足够的历史信息来判断某个数据行是否被一个事务修改过。当大量事务在短时间内并发地修改同一数据块就会出现以上情况。用户可以为可能被多个事务同时更新相同数据块的表设置较大的 INITRANS 值,以便避免上述情况。设置了较大的 INITRANS 值后,Oracle 就能为每个数据块分配足够的空间来记录访问此数据块的事务的信息。
当一个串行化事务试图更新或删除数据,而这些数据在此事务开始后被其他事务修改并进行了提交,Oracle 将报错:
ORA-08177: 无法进行串行化访问
当一个串行化事务因为 无法进行串行化访问 (Cannot serialize access)错误而失败时,应用程序可以 选择以下几种处理方式:
1、将错误发生之前的操作提交
2、执行其他操作(执行前可以回滚到事务内的某个保存点)
3、撤销整个事务
下图显示了一个事务遇到 无法进行串行化访问 后, 程序进行回滚并尝试重新执行此事务的例子:
图中显示了一个串行化事务,其中首先执行了两个相同的 SELECT 语句,接着执行了一个 UPDATE 语句。即便在两个 SELECT 执行之间有其他事务修改了相关数据,这两个 SELECT 也能够返回相同的结果。当 UPDATE 语句更新数据时,所更新的数据在此事务开始后被其他事务修改并提交过,Oracle 将报错 Cannot Serialize Access。这个错误将导致事务回滚并尝试重新执行。
已提交读取隔离与串行化隔离的区别
Oracle 为应用程序开发者提供了两种特性相异的事务隔离级别。已提交读取隔离和串行化隔离都能实现高度的数据一致性及并发访问能力。这两种隔离级别都能够利用 Oracle 的读一致性多版本并发访问控制模型及独有的行级锁(row-level locking)技术,从而减少并发事务间的竞争。应用程序开发者可以使用这两种隔离级别开发符合现实要求的应用系统。
事务集数据一致性
我们可以参考以下场景来研究 Oracle 中的两种隔离级别:假设现有一组数据库表(或称为一组数据集),一系列读取表数据的查询,以及一组在任意时间提交的事务。如果一个数据库操作(一个查询或一个事务)中所有读取返回的数据是由同一组已提交事务写入的,我们就称此操作满足事务集数据一致性(transaction set consistent)。相反,当一个数据库操作内的不同读取反映了不同事务集对数据的修改,此操作就不满足事务集数据一致性。换句话说,一个不满足事务集数据一致性的操作所看到的数据库的状态是由不同的已提交事务集决定的。
在已提交读取隔离模式下,Oracle 能保证每个语句的事务集数据一致性。而在串行化隔离模式下,Oracle 能保证每个事务的事务集数据一致性。
下表总结了 Oracle 中已提交读取事务和串行化事务的关键区别。
已提交读取 |
串行化 |
|
|
||
脏写入(dirty write) |
不可能 |
不可能 |
脏读取(dirty read) |
不可能 |
不可能 |
不可重复读取(nonrepeatable read) |
可能 |
不可能 |
不存在读取(phantom) |
可能 |
不可能 |
与 ANSI/ISO SQL 92 标准兼容 |
是 |
是 |
唯一的数据视图的使用范围 |
语句 |
事务 |
事务集数据一致性 |
语句级 |
事务级 |
行级锁 |
是 |
是 |
读操作(reader)阻塞写操作(writer) |
否 |
否 |
写操作阻塞读操作 |
否 |
否 |
针对不同数据行的写操作 是否相互阻塞 |
否 |
否 |
针对相同数据行的写操作 是否相互阻塞 |
是 |
是 |
等待导致阻塞的事务(blocking transaction) |
是 |
是 |
会出现
无法进行串行化访问
(Cannot
serialize access)错误 |
否 |
是 |
在导致阻塞的事务结束后 将发生错误 |
否 |
否 |
在导致阻塞的事务提交后 将发生错误 |
否 |
是 |
选择隔离级别
已提交读取隔离
对于大多数应用来说,已提交读取隔离是最适合的事务隔离级别。已提交读取隔离能够最大限度地保证数据并发性,但在某些事务中可能会出现不可重复读取或不存在读取,因此略微增加了出现数据不一致性的风险。
在对性能要求较高的系统中,为了应对较高的事务到来率(transaction arrival rate),系统需要提供更大的事务吞吐量和更快的响应速度,此时采用串行化隔离可能难以实现。还有一类系统,其事务到来率较低,出现不可重复读取或不存在读取的风险也较低。以上两种系统均适合采用已提交读取隔离 。
Oracle 的已提交读取隔离能够确保所有查询的事务集数据一致性。即查询获得的数据是处于一致性状态下的。因此在 Oracle 中已提交读取隔离能够满足大多数应用的要求。而在没有多版本并发访问控制的数据库管理系统中,开发者可能需要采用更高程度的隔离方式。
在已提交读取隔离模式下,开发者不需要在应用逻辑中捕获 无法进行串行化访问 错误,也无需回滚并重新执行事务。在大多数应用程序中,几乎不会有在一个事务中执行同一查询多次的情况,因此在这些应用程序中,为防止出现不可重复读取或不存在读取而采取的保护措施并不重要。 如果开发者选择已提交读取隔离,就能够省略在每个事务中加入错误检查及事务重做的代码。
Oracle 的串行化隔离适合于具备以下特点的系统:出现修改相同数据的事务的几率较小,且长时间执行的事务以只读操作为主。最适合采用串行化隔离的系统是大型数据库,且其中主要运行更新少量数据的短小事务。
串行化隔离能够提供更好的数据一致性,她能阻止不可重复读取或不存在读取的现象。当一个读或写事务中需要运行同一查询多次时,串行化隔离的作用更加明显。
某些数据库管理系统在实现串行化隔离时,无论读写操作都要对整个数据块加锁。而 Oracle 则采用了无阻塞查询及低粒度的行级锁技术,减少了读写操作间的竞争。对于存在较多读写竞争的应用,Oracle 的串行化隔离与其他数据库管理系统相比能够大大地提高事务处理能力。因此,某些应用在 Oracle 中可以采用串行化隔离,而在其他数据库管理系统则未必可行。
运行在串行化隔离模式下的事务中的所有查询所获得的数据都来自同一时间点,因此这种隔离级别适合于需要执行多个满足一致性的查询的事务。例如,汇总数据并将结果写入数据库的报表应用可以采用串行化隔离,因为串行化事务所提供的数据一致性与 READ ONLY 事务相同,但其中还可以执行 INSERT , UPDATE ,和 DELETE 操作。
参考至:Oracle 10G R2 Concepts
本文原创,转载请注明出处、作者
如有错误,欢迎指正
邮箱:czmcj@163.com
发表评论
-
Oracle 锁与锁争用
2015-05-08 02:13 4180大多数的锁都是行级 ... -
Oracle SQL Parsing
2014-07-30 22:24 1949Stages of SQL Processing Fig ... -
Oracle 11g中的direct path read(原创)
2014-06-16 23:01 5788在11g中,全表扫描可能使用direct path rea ... -
深入解析direct path read
2014-06-16 22:35 2598传统读取数据的 ... -
ORA-01555和延迟块清除
2014-06-16 21:13 206001555, 00000, "snapshot t ... -
Oracle(block clean out)的块清除
2014-06-16 21:09 1287Oracle(block clean out)的块清除Cl ... -
SCN之fast cleanout
2014-06-07 16:13 1751SQL> select dbms_rowid.row ... -
SCN之delayed block cleanout
2014-06-07 16:09 1195Block的cache header部分 ... -
Oracle rman change tracking CTWR(原创)
2014-04-25 11:10 2981block change tracking介绍Block c ... -
SSM自动段空间管理 简介
2014-03-27 19:46 1360因为ASSM的官方文档很少,经过多次的查证之后,终于弄明白了 ... -
undo表空间相关(原创)
2014-03-25 21:48 2111DML语句与undo ... -
Bitmap Index vs B-tree Index(原创)
2014-03-08 21:09 1532Introduction Conventional wi ... -
bitmap索引的深入研究
2014-03-08 14:59 1465位图(bitmap)索引是另外一种索引类型,它的组织形式与 ... -
Oracle 10g/11g Latch机制的变化
2013-01-09 18:57 1548Oracle 10g/11g Latch机制 ... -
ASM内部原理(原创)
2012-12-24 21:55 9950ASM的SGA组成 ASM实例 ... -
ASM的元数据(原创)
2012-12-18 21:16 3070概述 ASM Filesystem是建立在ASM D ... -
Oracle数据块深入分析总结
2012-04-23 12:51 7912最近在研究块的内部结构,把文档简单整理了一下,和大家分享一下。 ... -
深入理解重建索引(原创)
2012-04-10 16:58 20795什么时候需要重建索引 ... -
Oracle中B-TREE索引的深入理解(原创)
2012-04-09 20:59 15938索引概述 索引与表一样,也属于段(segment)的 ... -
深入理解Oracle中的latch(原创)
2012-04-04 18:17 11169串行化 概述 串行化 - 数据库系统本 ...
相关推荐
为了对抗日益复杂的威胁,Android系统还在不断演进,引入了如运行时权限管理、动态权限检查、应用程序隔离等新特性。例如,Android Marshmallow及更高版本开始,用户可以在运行时为应用授予或撤销权限,增强了用户对...
ANDROID安全架构深究.pdf ANDROID安全架构深究.pdf ANDROID安全架构深究.pdf
深究动画精神家园.doc
过分深究可能会导致时间浪费,而且有些高级主题需要在具备一定基础后才能更好地理解。 6. 从基础做起,稳步前行:初学者应专注于基础概念,如SQL语法、表空间管理、备份恢复等。这些是理解Oracle核心的基础。随着...
本资源“ANDROID安全架构深究”深入探讨了这一主题,为开发者和安全研究者提供了宝贵的洞察力。以下是对Android安全架构的详细解读: 1. **权限管理系统**:Android的权限模型是基于权限的,每个应用在安装时都会被...
根据提供的文件信息,我们可以深入探讨《Android安全架构深究》这一主题所涵盖的关键知识点。由于提供的文本内容较少,以下分析将基于标题、描述以及通常情况下此类书籍可能涉及的主题来进行。 ### Android安全架构...
本主题“C语言外挂编写深究”将围绕如何使用C语言编写游戏外挂进行深入探讨,特别是结合Windows操作系统来实现这一目标。 首先,我们需要理解C语言的基础知识,包括变量、数据类型、运算符、流程控制等基本概念。这...
c语言辅助编写深究 c语言辅助编写深究 c语言辅助编写深究 c语言辅助编写深究 c语言辅助编写深究 c语言辅助编写深究
《ANDROID安全架构深究》是美国作者Nikolay Elenkov的一本深入探讨Android操作系统安全性的著作。这本书详尽地阐述了Android系统的安全模型、设计原则以及如何保护应用程序和设备免受各种威胁。Android作为全球最...
ANDROID安全架构深究_(美)NIKOLAY ELENKOV著;刘惠明,刘跃译;(美)JON SAWYER作序;诸葛建伟审校;诸葛建伟组织翻译_北京:电子工业出版社
深究诗歌赏析教学.doc
深究高中语文课堂提问.doc
农村区域经济发展深究.docx
高校校园景观设计深究.doc
深究电视公益慈善节目.doc
指向深度学习的高中化学事实性知识内涵深究及教学建议——以“钠及其化合物”为例.pdf
深究保护环境合理利用资源.doc