事务

Transaction

事务介绍

事务是包含一个或多个 SQL 语句的逻辑的、 原子的工作单元。事务将SQL 语句分组,以便它们可以一起被提交,即将其应用到数据库,或者一起被回滚,即将其从数据库中撤消。Oracle 数据库将为每个事务分配一个称为事务ID的唯一标识符。使用事务是数据库管理系统有别于文件系统的最重要方式之一。

所有 Oracle 事务都符合称为 ACID 属性的数据库事务的基本属性。ACID是以下的缩写:

原子性, 事务中的所有任务,要么全部执行,要么都不执行。不存在部分完成的事务。例如,如果事务启动并欲更新 100 行,但在系统在完成20行更新后出现故障,则数据库会回滚这 20 行更新。

一致性, 事务会将数据库从一个一致状态变为另一个一致状态。例如, 在从一个储蓄账户借记、并从一个支票账户贷记的银行事务中,故障一定不能导致数据库仅仅贷记一个账户,这会导致数据不一致。

隔离性, 一个事务必须在被提交之后,其它事务才能看见其效果。例如,正在更新 hr.employees表的一个用户,不会看到由另一个用户在employees表上未提交的更改。因此,对这些用户来说,这些事务好像是串行执行的。

持久性,已提交的事务所做的更改是永久性的。事务完成后,数据库通过其恢复机制,确保在事务中所做的更改不会丢失。

事务的结构

数据库事务由一个或多个语句组成。具体而言,事务包含下列之一:

一个或多个数据操作语言 (DML) 语句一起构成的、对数据库的一个原子更改。

一个数据定义语言 (DDL) 语句。

事务的开始

事务开始于所遇到的第一个可执行 SQL 语句。可执行的SQL 语句是能产生数据库实例调用的SQL 语句,包括 DML 和 DDL 语句,及SET TRANSACTION语句。

当事务开始时, Oracle 数据库将为事务分配一个可用的撤销数据段,以记录新事务的撤消条目。数据库在第一个 DML 语句过程中,首先会分配撤销段和事务表槽,然后分配事务 ID。事务 ID 对于事务来说是唯一的,并由撤销段号、 槽号、和序列号来表示。

事务的结束

事务在出现以下操作时结束:

用户在没有SAVEPOINT子句的语句中发出COMMIT或ROLLBACK。提交意味着用户会显式或隐式地请求事务中所做的更改被持久化。只有在提交事务之后,事务所做的更改才是永久性的,并对其他用户可见。

用户运行一个DDL 命令,如CREATE、DROP、RENAME、或 ALTER等。数据库在每个 DDL 语句之前和之后发出一个隐式的COMMIT 语句。如果当前事务中包含 DML 语句,则Oracle 数据库首先提交该事务,然后将该 DDL 语句作为一个新的单语句事务来运行并提交。

用户从大多数 Oracle 数据库实用程序和工具正常退出,导致当前事务被隐式提交。当用户断开连接时的提交行为依赖于应用程序,并且是可配置的。

客户端进程异常终止,导致数据库使用存储在事务表和撤销段中的元数据来隐式回滚其事务

一个事务结束后, 下一个可执行的 SQL 语句将自动启动后续事务。

语句级原子性

Oracle 数据库支持语句级原子性,这意味着 SQL 语句是一个原子工作单元,要么完全成功,要么完全失败。

成功的语句不同于已提交事务。如果一个SQL 语句能被数据库正确分析,并作为一个原子单位来运行且未产生错误,且所有行都被正确更改,则这个SQL 语句是成功执行的。

如果 SQL 语句在执行过程中导致错误,则它是不成功的,该语句中的所有影响都将被回滚。此操作是一个语句级回滚。此操作具有以下特征:

未成功的 SQL 语句只会导致它本身执行的工作丢失。未成功的语句不会导致丢失当前事务中该语句之前的任何工作。

回滚的效果是,好像该语句从来未运行过。

系统更改号 (SCNs)

系统更改号 (SCN) 是一个由 Oracle 数据库使用的逻辑、 内部的时间戳。SCN按数据库中发生的事件排序,以满足在事务ACID 属性的需要。Oracle 数据库使用 SCN来标记某个位置,在其之前的所有更改都被认为已写到磁盘上,以避免在恢复过程中应用不必要的重做。数据库还使用 SCN来标记一个其数据不存在重做信息的点,以便恢复过程可以在该点停止。

SCN是按单调递增的顺序发生的。Oracle 数据库可以像使用时钟一样使用SCN,因为一个SCN观察值指示一个逻辑时间点,而其重复观察值相比之前会相同或更大。若一个事件的SCN比另一个事件的SCN低,则它在数据库中发生在一个更早的时间。几个事件可以共享相同的 SCN, 这意味着他们在数据库中同时发生。

每个事务都有一个SCN。例如,如果事务更新了一行,则数据库记录此更新发生时的SCN。此事务中其他修改具有相同的SCN。当事务提交时,数据库将为此提交记录一个SCN。

Oracle 数据库在系统全局区域(SGA)中递增 SCN。事务中修改数据时,数据库会将一个新的SCN写入到分配给事务的撤销数据段。然后日志写入器进程立即将事务的提交记录写入在线重做日志。提交记录具有事务的唯一 SCN。Oracle 数据库还使用 SCN作为其实例恢复和介质恢复机制的一部分。

事务控制概述

事务控制即管理DML 语句所做的更改,和将DML 语句分组为事务。一般情况下,应用程序设计人员都关注事务控制,以便工作能按逻辑单元来完成,且数据能保持一致。

事务控制涉及使用下面的语句:

COMMIT 语句结束当前事务,并使在事务中执行的所有更改都具有持久性。提交还会清除在事务中的所有保存点,并释放事务锁。

ROLLBACK 语句将取消当前事务中所做的工作;它导致所有自上次提交或回滚以来的数据更改被丢弃。ROLLBACK TO SAVEPOINT语句将撤消自上次保存点以来所做的更改,但不会结束整个事务。

SAVEPOINT语句标识在事务中您可以稍后回滚到的点。

事务名称

事务名称是一个由用户指定的可选标记,作为工作中正在执行的事务中的一个提示。你使用SET TRANSACTION ... NAME语句来为事务命名,如果要用它,则它必须是事务的第一个语句。

事务名称提供了以下优点:

有助于监测长时间运行的事务,并解决可疑的分布式事务。

您可以在应用程序中查看事务名称及其相应事务 ID。例如,数据库管理员可以在监视系统活动时,在Oracle 企业管理器 (企业管理器)中查看事务名称。

数据库将事务名称写入事务的审计重做记录,因此您可以使用 LogMiner 来搜索在重做日志中的特定事务。

可以使用事务名称在 V$TRANSACTION之类的数据字典视图中查找特定的事务。

活动事务

活动事务即是已开始但尚未提交或回滚的事务。在事务提交或回滚之前,事务对数据所做的更改是暂时的。在事务结束之前,数据的状态如下所示:

Oracle 数据库已在系统全局区(SGA)中生成撤消数据信息

Oracle 数据库已在SGA 的联机重做日志缓冲区中生成了重做信息。

已经对 SGA中的数据库缓冲区进行了更改。

数据更改所影响的行已被锁定。

保存点

保存点是事务上下文中的一个由用户声明的中间标记。在内部,此标记将被解析为一个SCN。保存点将长事务划分为多个更小的部分。

如果你在一个长事务中使用保存点,则您就可以在之后将事务中执行的工作回滚到当前时间之前,却又在事务中声明的某个保存点之后。因此,如果您出了错,您不需要重新提交所有每个语句。

回滚到保存点

在未提交事务中回滚到某个保存点,意味着该指定的保存点之后所做的任何更改都将被撤消,但它并不意味着事务本身的回滚。当一个事务回滚到一个保存点时,将执行以下操作:

1 Oracle 数据库将只回滚在该保存点之后运行的语句。

2 Oracle 数据库保留在ROLLBACK TO SAVEPOINT语句中指定的保存点,但随后的所有保存点都将丢失。

3 Oracle 数据库释放在指定保存点之后获取的所有表锁和行锁,但保留在该保存点之前获取的所有数据锁。

排队事务

取决于当时的场景,之前在等待被锁定资源的事务,在回滚到保存点后,可能仍处于阻塞状态。一个事务被另一个事务阻塞时,它会在阻塞事务后面排队,因此整个阻塞事务必须提交或回滚,被阻塞的事务才能得以继续。

事务回滚

未提交事务的回滚,将撤消已由事务中的SQL 语句执行过的任何数据更改。事务回滚后,事务中所做工作的影响就不再存在。

对未引用任何保存点的整个事务的回滚, Oracle 数据库执行下列操作:

通过使用相应的撤销段,撤消事务中所有 SQL 语句所做的所有更改。每个活动事务的事务表条目包含一个指向该事务的所有撤消数据 (与应用顺序相反)的指针。数据库从撤销段中读取数据,反转其操作,然后将撤消条目标记为已应用。因此,如果一个事务插入行,则其回滚删除行。如果一个事务更新行,则其回滚反转这个更新。如果一个事务删除一个行,则其回滚重新插入该行。

释放由事务持有的所有数据锁。

清除在事务中的所有保存点。

事务提交

提交结束当前事务,并使事务中执行的所有更改持久化。当一个事务提交时,将发生以下操作:

为提交生成系统更改号 (SCN)。在关联的回滚表空间的内部事务表中记录已提交的事务。分配相应的唯一事务SCN,并将其记录在事务表中。

日志写入器 (LGWR)进程将重做日志缓冲区中的剩余重做日志条目写入到在线重做日志中,并将事务SCN写入到在线重做日志中。这个原子事件是提交事务的本质所在。

Oracle 数据库释放在行和表上持有的锁。

Oracle 数据库删除保存点。

Oracle 数据库执行一个提交清理。如果包含已提交的事务的被修改数据块仍处于SGA中,也没有其他会话正在对他们进行修改,则数据库从该块中删除与锁相关的事务信息。理想情况下,COMMIT会清理该数据块,以便后续的SELECT

操作不必再执行此任务。

Oracle数据库将事务标记为完成。

事务提交后,用户可以查看所做的更改。通常,提交是一个快速的操作,而与事务大小无关。提交的速度不会随着在事务中修改的数据的大小的增大而增加。提交的最长部分是由 LGWR 执行的物理磁盘I/O。然而,LGWR 所用的时间量却减少了,因为它一直在在后台以增量方式写出重做日志缓冲区中的内容。

默认行为是, LGWR 必须将重做数据同步地写入联机重做日志,而事务必须等到被缓冲的重做数据被写到磁盘上之后,提交操作才能返回到用户。但是,为取得更低的事务提交延迟,应用程序开发人员可以指定重做被异步写入,以便事务不需要等待重做被写入磁盘,就可以立即从COMMIT调用返回。

自治事务概述

自治事务是一个独立的事务,可以从另一个称为主事务的事务中调用。你可以挂起调用事务、 在自治事务中执行 SQL 操作并提交或回滚它们,然后继续执行调用事务。自治事务对于那些必须独立执行、而不管调用事务是否提交或回滚的操作 非常有用。

自治事务具有以下特征:

自治事务不会看见在主事务中所做的未提交更改,也不与主事务共享锁或资源。

自治事务中的更改在其提交后对其它事务是可见的。因此,用户可以立刻访问更新的信息,而不必等到主事务提交。

自治事务可以启动其他自治事务。没有关于自治事务能调用多少级别的任何限制,这只受限于可用的资源。

分布式事务概述

分布式数据库是在分布式系统中,可以对应用程序而言,作为单一数据源出现的一组数据库。分布式事务,包括一个或多个使用称为数据库链接的模式对象的语句,更新位于分布式数据库中两个或更多不同节点上的数据。数据库链接描述一个数据库实例如何登录到另一个数据库实例的方式。

与本地数据库上的事务不同,分布式事务变更多个数据库上的数据。因此,分布式事务处理更复杂,因为数据库必须进行协调,以将事务中所做的更改作为一个原子单元提交或回滚。必须提交或回滚整个事务。Oracle 数据库必须通过网络协调事务控制,并保持数据的一致性,即使发生网络或系统故障。

两阶段提交

两阶段提交机制保证参与分布式事务的所有数据库,要么都提交、或者要么都回滚事务中的语句。该机制还可以保护由完整性约束、 远程过程调用、和触发器执行的隐式 DML。

在涉及多个数据库的两阶段提交中,由某个数据库协调该分布式事务。发起的节点称为全局协调者。协调者询问其他数据库是否已准备好提交。如果任何数据库响应说未准备好,则整个事务回滚。如果所有数据库都说已准备好,则协调者将广播一个消息,使该提交在每个数据库上持久化。

两阶段提交机制对发出分布式事务的用户是透明的。事实上,用户甚至不需要知道事务是分布式的。表示事务结束的 COMMIT语句自动触发两阶段提交机制。在数据库应用程序正文中不需要额外编码或复杂的语句语法来包括分布式事务。

可疑事务

可疑分布式事务,发生在两阶段提交被任何类型的系统或网络故障中断时。例如,两个数据库向协调数据库报告他们已准备提交,但协调数据库实例收到消息后却立即失效了。这两个准备提交的数据库现在被挂起,而他们还在等待通知结果。

恢复器 (RECO) 后台进程会自动解决可疑分布式事务的残局。该故障修复和通信重新建立后,在所有涉及到的节点上,每个本地的 Oracle 数据库的RECO进程一致地自动提交或回退任何可疑的分布式事务。

对于长时间失败的情况, Oracle 数据库使每个本地管理员手动提交或回滚任何由于失败引起的可疑分布式事务。此选项使本地数据库管理员能够释放任何由于长期的失败所引起的无限期持有资源锁定。

如果数据库必须恢复到过去的某个时间,则数据库恢复工具使得在其它站点的数据库管理员能将其数据库返回到某个过去的时间点。此操作可确保全局数据库保持一致。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25427762/viewspace-1064104/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25427762/viewspace-1064104/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值