数据并发和一致性介绍

在单用户的数据库中,用户可以修改数据,而不用担心其他用户在同一时间修改相同的数据。但是,在一个多用户的数据库中,多个事务内的语句可以同时更新相同的数据同时执行的多个事务必须产生有意义且一致的结果。因此,多用户数据库必须提供以下功能:

数据并发性,确保多个用户可以同时访问数据

数据一致性,确保每个用户看到数据的一致的视图,包括可以看到用户自己的事务所做的更改,和其他用户已提交的事务所做的更改

为描述当多个事务同时运行时的事务一致性行为,数据库研究人员定义了一种称为可串行性的事务隔离模型可串行化事务在一种使其看起来好像没有其他用户正在修改数据库中的数据的环境中运作

虽然事务之间的这种隔离度好像不错,但在可序列化模式下运行许多应用程序可能会严重影响应用程序吞吐量。对并发运行事务的完全隔离可能意味着一个事务无法在某个正在被另一个事务查询的表上执行插入操作。简而言之,现实的考虑通常需要在完美的事务隔离性和性能之间的一个折衷。

Oracle 数据库通过使用多版本一致性模型和各种类型的锁和事务,来维护数据的一致性。通过这种方式,数据库可以向多个并发用户呈现一个数据的视图,每个视图都在某个时间点上是一致的因为不同版本的数据块可以同时存在,事务可以读取在某个查询请求时间点上的已提交版本数据,并返回符合一个单一时间点的结果

语句级读取一致性

Oracle 数据库始终强制执行语句级读取一致性,保证单个查询所返回的数据是已提交的、且关于某个单一时间点一致单个 SQL 语句所一致的时间点取决于事务的隔离级别和查询的性质

在读提交隔离级别(read committed isolation level),该时间点是语句打开的时间。例如,如果一个 SELECT 语句在SCN 1000时打开,则此语句一致于SCN 1000。

在可串行化或只读事务隔离级别(serializable or read-only transaction),该时间点为事务开始的时间。例如,如果一个事务开始于SCN 1000,且在该事务中有多个 SELECT 语句发生,则每个语句都一致于SCN 1000。

在闪回查询操作(SELECT … AS OF)中,SELECT 语句显式指定时间点。例如,你可以查询某个表在上星期四下午 2 时的数据。

事务级读取一致性

Oracle 数据库还可以为一个事务中的所有查询提供读取一致性,这称为事务级读取一致性。在这种情况下,事务中的每个语句都看到来自同一时间点(即该事务开始的时间)的数据

在一个可序列化事务中的多个查询,能看到事务本身所做的更改。例如,某个事务更新了employees表,然后其后续查询将看到对employees所做的更新。事务级读取一致性产生可重复的读取,且不会产生幻读(phantom reads)

读取一致性及撤消(undo segment)

为管理多版本的读取一致性模型,当表同时被查询和更新时,数据库必须创建一组读取一致的数据。Oracle 数据库通过使用撤销数据实现了这一目标。

每当用户修改了数据,Oracle数据库会创建撤销条目,并写入到撤销段 (“撤销段”)。撤销段包含由未提交事务或最近提交的事务所更改的数据的旧值。因此,同一数据在各个不同时间点上的多个版本,都可以存在于数据库中数据库可以使用在不同时间点的数据快照,来提供数据读取一致视图,并实现非阻塞查询

读取一致性在单实例和 Oracle 真正应用集群 (Oracle RAC) 环境中都可以得到保证。Oracle RAC 使用一种称为缓存融合的“缓存到缓存”的数据块传输机制,将一个数据库实例中的数据块读取一致映像传送到另一个实例中。

读一致性:示例

图 9-1 显示了一个查询,在已提交读隔离级别(read committed isolation level)使用撤销数据以提供语句级的读取一致性。

这里写图片描述

当数据库为某个查询检索数据块时,数据库确保每个块中的数据反映了该查询开始时的内容。数据库根据需要回滚对数据块所做的更改,以将块重建到查询处理开始的状态。

数据库使用一种称为SCN的机制,来保证事务的顺序。当SELECT 语句进入执行阶段时,数据库会确定查询开始执行时所记录的SCN。在图 9-1中, 该SCN为10023。在事务中的每个查询必须返回在SCN 10023时的已提交数据。

在图 9-1中,其SCN大于10023的块具有已更改数据,如图中的两个具有SCN 10024的块所示。SELECT 语句需要一个与已提交更改块一致的版本。该数据库将当前数据块复制到新的缓冲区,并应用撤消数据,以重新构造块的早期版本。这些重建的数据块被称为一致读取 (CR) 克隆。

在图 9-1中,数据库创建了两个 CR 克隆: 一个块与SCN 10006一致,而另一个块与SCN 10021 一致。数据库为查询返回重建的数据。通过这种方式,数据库可以防止脏读。

读取一致性和事务表

数据库使用一个称为感兴趣事务列表(interested transaction list) (ITL) 的事务表,来确定当数据库开始修改块时是否某个事务还未提交。每个段块的块头包含一个事务表

事务表中的条目描述了哪些事务有被锁定的行,以及块中的哪些行包含提交和未提交的更改。事务表指向撤销段,提供对数据库所做的更改的时间相关信息

在某种意义上,块头包含影响块中每个行的事务的最近历史记录。CREATE TABLE和ALTER TABLE语句的INITRANS参数,控制被保留的交易历史记录条数

锁定机制

通常,多用户数据库使用某种形式的数据锁定,来解决与数据并发性、一致性、和完整性相关的问题锁是防止访问同一资源的事务之间的破坏性相互作用的机制

ANSI/ISO 事务隔离级别

已由 ANSI 和 ISO/IEC 采纳的SQL 标准,定义了四个事务隔离级别。这些级别对事务处理吞吐量有不同程度的影响

这些隔离级别根据在同时运行的事务之间必须防止的现象来定义。可预防的现象有:

 脏读

一个事务读取了已被另一个事务写入、但尚未提交的数据。

 不可重复(模糊)读

一个事务重新读取之前曾经读取过的数据,发现另一个已提交的事务已修改或删除了该数据。例如,用户查询某行,然后稍后又查询相同的行,却发现数据已更改。

 幻像读

一个事务重新运行满足某搜索条件的查询,并返回一个行集,发现另一个已提交的事务已插入了满足搜索条件的其他行。

例如,一个事务查询雇员数目。五分钟后它执行相同的查询,但现在人数却增加了一个,这是因为另一个用户为一名新员工插入了一条记录。满足查询条件的数据比之前更多了,但与不可重复读不同,之前读取的数据不会变化

根据运行在某个特定的隔离级别的事务所允许发生的现象,SQL 标准定义了四个隔离级别。表 9-1 显示了这些级别。

这里写图片描述

Oracle 数据库提供了已提交读 (默认值)和可串行化隔离级别。另外,数据库也可以提供一种只读模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值