数据并发性和一致性介绍--Data Concurrency and Consistency

概要

在单用户数据库中,用户可以修改数据而不用关心其他用户同时修改同样的数据,然而,在多用户数据库中,多个同时发生的事务的语句可以更新同样的数据,而同时执行的事务必须产生有意义且一直的结果,因此,多户用数据库必须提供以下内容:

  • 数据并发性:它确保用户可以同时访问数据;
  • 数据一致性:它确保每个用户都能看到数据的一致性视图,包括用户自己事务中所做的可见的更改和其他用户事务中已提交的更改。

要描述事务并发运行时的一致性事务行为,数据库研究人员定义了一个称为serializability的事务隔离模型。在一个环境中运行的序列化(serializable)事务使它看起来好像没有其它用户在数据库中修改数据。

虽然事务之间的隔离程度通常是可取的,但在序列化模式下运行许多应用程序会严重危害应用程序的吞吐量。并发运行事务的完全隔离可能意味着一个事务不能在另一个事务正在查询的表中执行插入操作。简言之,现实世界的考虑通常需要在完美的事务隔离和性能之间做出妥协。

Oracle数据库通过使用多版本一致性模型(multiversion consistency model)、各种类型的锁和事务来维护数据一致性。通过这种方式,数据库将会给多个并发用户呈现数据的视图,每个视图与某个时间点一致。由于数据块(data blocks)的不同版本可以同时存在,事务可以读取发出查询的那个时间点所需的提交的数据的那个版本,同时返回与该时间点相一致的结果。

多版本读一致性(Multiversion Read Consistency)

在Oracle数据块中,多版本化是同时实现多版本数据的能力。Oracle数据块维护多版本读一致性,这意味着数据块查询具有以下特性:

  • 读一致性查询
    查询返回的数据是提交的,并与单个时间点一致。
    Oracle数据块从不允许脏读,脏读是在一个事务读取另一个事务未提交的数据时发生。
  • 非阻塞查询
    数据的读和写不会相互阻塞。

语句级读一致性

Oracle数据库总是强制执行语句级读一致性,这保证了单个查询返回的数据是提交的,并且与单个时间点(point in time )上相一致。单个SQL语句在某个时间点(point in time)的一致性取决于事务的隔离级别和查询的特性:

  • 在读提交(read committed)隔离级别,该点(point)是语句打开的时间;
  • 在序列化和只读事务中,该点(point)是事务开始的时间;
  • 在闪回查询(select 。。。 as of)操作中,select语句显式指定该点(point in time)。

事务级读一致性

Oracle数据库也可以为事务中的所有查询提供读一致性,称为事务级读一致性。在这种情况下,事务中的每个语句都从同一个point in time 看到数据,该point是事务开始的时间。

序列化(serializable)事务中所做的查询能够看到事务本身所做的更改,事务级读一致性产生可重复读取,并且不会产生幻读。

读一致性和Undo段

为管理多版本读一致性模型,当表被同时查询和更新时,数据库必须创建一个读一致性数据集,Oracle数据库通过undo data来完成这一目标。

当用户修改数据时,Oracle数据库创建undo entry,并将其写入undo段。undo段包含未提交的或最近提交的事务更改的数据的旧值。因此,相同数据的多个版本,在不同的时间点上,都存在于数据库中。数据库可以在不同的时间点使用数据快照提供数据的一致性视图,并启用非阻塞查询。

读一致性在单实例和Oracle RAC环境得到保证,Oracle RAC使用被称为cache fusion的缓存到缓存的传输机制,将数据块的读一致性镜像从一个数据库实例传输到另一个实例。

Lock机制

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

具体见Oracle数据库锁机制。

ANSI/ISO事务隔离级别

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

这些隔离级别是根据并发执行事务之间必须规避的现象来定义的,可规避的现象是:

  • 脏读(Dirty reads)
    事务读取被另一个事务写但是还没提交的数据;
  • 不可重复读(Nonrepeatable reads)
    事务重新读取之前读过的数据,并发现另一提交的事务已经修改或删除了数据;
  • 幻读(Phantom reads)
    事务重新运行返回搜索条件的行的查询,并发现另一提交事务已插入了满足该条件的其他行。

SQL标准定义了4种隔离级别:

Isolation Level Dirty Read Nonrepeatable Read Phantom Read
Read uncommitted Possible Possible Possible
Read committed Not possible Possible Possible
Repeatable read Not possible Not possible Possible
Serializable Not possible Not possible Not possible

Oracle数据库提供了read committed(默认)和serializable隔离级别,另外,数据库提供只读模式。
具体见Oracle数据库隔离级别概览

参考:官方文档

原文地址:https://www.cnblogs.com/alen-liu-sz/p/12975703.html