参考官方文档:
http://docs.oracle.com/cd/E11882_01/server.112/e40540/transact.htm#CNCPT016
https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/transactions.html#GUID-B97790CB-DF82-442D-B9D5-50CCE6BF9FBD
一个事务是保护一个或多个SQL 语句的,一个逻辑,原子工作单元。事务对SQL语句进行分组,以便它们都被提交,这意味着它们被应用于数据库,或者全部回滚。Oracle数据库为每个事务分配一个称为事务ID的唯一标识符。
所有Oracle事务都符合数据库事务的基本属性,称为ACID属性。ACID是以下缩写:
1.Atomicity 原子性
一个事务的所有任务都执行或者都不执行。没有部分事务。例如,如果事务开始更新100行,但是系统在之后进行20次update后失败,那么数据库会回滚这20行的变更。
2.Consistency 一致性
事务将数据库从一个一致的状态带到另一个一致的状态。例如,在借记储蓄账户并记入支票账户的银行交易中,失败不能导致数据库仅授予一个帐户,从而导致数据不一致。
3.Isolation 隔离
在事务提交之前,事务的影响是不可见的。例如,一个更新hr.employees表的用户看不到另一个用户同时进行的未提交的员工更改。因此,作为用户看起来似乎事务正在顺序执行。
4.Durability 持久性
被提交事务产生的变更是永久性的。事务完成后,数据库通过其恢复机制确保事务的更改不会丢失。
--事务的使用是数据库管理系统与文件系统不同的最重要的方式之一。
简单事务的例子
为了说明交易的概念,请考虑银行数据库。
当客户将钱从储蓄帐户转移到支票帐户时,交易必须包含三个单独的操作:
Oracle数据库必须允许两种情况。如果所有三个SQL语句都使帐户保持适当的平衡,则可以将事务的影响应用于数据库。但是,如果诸如资金不足,帐号无效或硬件故障之类的问题阻止了事务中的一两个语句完成,则数据库必须回滚整个事务,以便所有帐户的余额正确。
下图说明了银行交易。第一条语句从储蓄帐户3209减去$500。第二条语句向支票帐户3208添加$500。第三条语句将转帐记录插入日记表。最后的语句提交事务。

一个事务的结构:
数据库事务由一个或多个语句组成。具体来说,事务由以下之一组成:
1.一个或多个数据操作语言(DML)语句共同构成对数据库的原子更改
2.一个DDL(数据定义语言)语句
一个事务有一个开始和一个结束
1.开始一个事务
当遇到第一个可执行SQL语句时,事务开始。可执行SQL语句是一个SQL语句,用于生成对数据库实例的调用,包括DML和DDL语句以及SET TRANSACTION语句。
事务开始时,Oracle数据库将事务分配给可用的undo数据段,以记录新事务的undo条目。直到在第一个DML语句中分配了一个撤销段和事务表槽,才会分配一个事务ID。事务ID对事务是唯一的,表示undo段号,slot(槽位)和序列号。
以下示例执行一个UPDATE语句来开始一个事务并查询V$TRANSACTION以了解有关事务的详细信息:
UPDATE hr.employees SET salary=salary;
SELECT XID AS "txn id", XIDUSN AS "undo seg", XIDSLOT AS "slot", XIDSQN AS "seq", STATUS AS "txn status" FROM V$TRANSACTION;
txn id undo seg slot seq txn status
---------------- ---------- ---------- ---------- ----------------
0600060037000000 6 6 55 ACTIVE
2.结束一个事务
当发生以下任何操作时,事务结束:
-用户发出没有SAVEPOINT子句的COMMIT或ROLLBACK语句。
在提交中,用户显式或隐式地要求将事务中的更改设置为永久性。事务所做的更改只有在事务提交后才能永久显示给其他用户。
-用户运行了一个DDL 命令,例如:CREATE, DROP, RENAME, 或 ALTER.
数据库在每个DDL语句之前和之后发出一个隐式的COMMIT语句。如果当前事务包含DML语句,则Oracle数据库首先提交事务,然后运行并将DDL语句提交为新的单语句事务。
-用户从大多数Oracle数据库实用程序和工具正常退出,导致当前事务被隐式提交。用户断开连接时的提交行为是依赖于应用程序和可配置的。
注意:在程序终止之前,应用程序应该始终显式地提交或撤消事务。
-客户端进程异常终止,导致使用存储在事务表和undo段中的元数据隐式地回滚事务。
一个事务结束后,下一个可执行SQL语句将自动启动下一个事务。下面的示例执行UPDATE以启动事务,以ROLLBACK语句结束事务,然后执行UPDATE以启动新事务(请注意,事务ID不同):
SQL> UPDATE hr.employees SET salary=salary;
107 rows updated.
SQL> SELECT XID, STATUS FROM V$TRANSACTION;
XID STATUS
---------------- ----------------
0800090033000000 ACTIVE
SQL> ROLLBACK;
Rollback complete.
SQL> SELECT XID FROM V$TRANSACTION;
no rows selected
SQL> UPDATE hr.employees SET last_name=last_name;
107 rows updated.
SQL> SELECT XID, STATUS FROM V$TRANSACTION;
XID STATUS
---------------- ----------------
0900050033000000 ACTIVE
语句级别的原子性:
Oracle数据库支持语句级原子性,这意味着SQL语句是一个原子的工作单元,完全成功或完全失败。
一个成功的语句和一个提交的事务不同。如果数据库解析并将其作为原子单元运行而无错误,则单个SQL语句将成功执行,就像在多行更新中更改所有行时一样。
如果SQL语句在执行期间导致错误,那么它不成功,因此语句的所有效果都将回滚。此操作是一个语句级的回滚。此操作具有以下特点:
-一个不成功的SQL语句只会造成它本身会执行的工作的丢失。
不成功的语句不会导致当前交易中之前任何工作的损失。例如,如果执行图10-1中的第二个UPDATE语句导致错误并回滚,则第一个UPDATE语句执行的工作不会回滚。第一个UPDATE语句可以由用户显式提交或回滚。
-语句回滚的效果好像该语句从未被执行
原子语句的任何副作用,例如在语句执行时调用的触发器,都被认为是原子语句的一部分。作为原子语句的一部分,生成的所有工作都成功或没有。
--也就是 触发器的原语句回滚,那么其插入的数据也会相应的回滚。
导致语句级别回滚的错误的示例是尝试插入重复的主键。涉及到死锁的单个SQL语句(即相同数据的竞争)也可能导致语句级别的回滚。但是,在SQL语句解析期间发现的错误(如语法错误)尚未运行,因此不会导致语句级别的回滚。
事务控制
事务控制是对DML语句所做的更改以及将DML语句分组到事务中的管理。一般来说,应用程序设计者关心事务控制,以便以逻辑单元完成工作,数据保持一致。
事务控制涉及使用以下语句:
-COMMIT语句结束当前事务,并使事务中执行的所有更改都是永久性的。COMMIT还会擦除事务中的所有保存点并释放事务锁。
-ROLLBACK语句回滚了当前事务中完成的工作; 它会导致自上次的COMMIT或ROLLBACK以来的所有数据更改被丢弃。ROLLBACK TO SAVEPOINT语句undo自上一个保存点以来的更改,但不会结束整个事务。
-SAVEPOINT语句标识可以稍后回滚的事务中的一个点。
事务名称:
事务名称是可选的用户指定的标记,用于提醒事务正在执行的工作。您使用SET TRANSACTION ... NAME语句命名事务,如果使用,则必须是事务的第一个语句。
事务名称具有以下优点:
1.让监控长时间的事务和解决分布式事务问题更容易。
2.您可以在应用程序中查看事务名称以及事务ID。例如,当监视系统活动时,数据库管理员可以在Oracle Enterprise Manager(企业管理器)中查看事务名称。
3.数据库将事务名称写入事务审计重做记录,因此可以使用LogMiner在redo中搜索特定事务。
4.您可以使用事务名称来查找数据字典视图中的特定事务,例如V $ TRANSACTION。
活动的事务:
一个活动事务是被启动,但是还未提交或回滚的事务。
事务进行的数据更改是暂时的,直到事务提交或回滚为止。在事务结束之前,数据的状态如下:
1.在SGA中 oracle 数据库生成undo 数据信息
undo数据包含由事务的SQL语句更改的旧数据值
2.Oralce数据库在SGA中的log buffer 中生成 redo
重做日志记录包含数据块的更改和undo块的更改
3.在SGA 中的buffer cache中变更发生。
存储在SGA的数据库缓冲区中的已提交事务的数据更改不一定由数据库写入程序(DBW)立即写入数据文件。磁盘写入可能发生在提交之前或之后。
4.受数据更改影响的行被锁定。
其他用户无法更改受影响的行中的数据,也不能看到未提交的更改
savepoints
savepoint 是一个事务上下文中用户声明的中间标记。在内部,这个标记被解析为SCN。savepoint将长事务分成较小的部分。
如果你在长事务中使用 savepoints,那么你有选项可以在发生错误时,不用重新提交每个语句。
在未提交的事务中回滚到保存点意味着撤消在指定的保存点之后所做的任何更改,但这并不意味着事务本身的回滚。当一个事务回滚到一个保存点时,就像在表10-1中运行ROLLBACK TO SAVEPOINT after_banda_sal一样,发生以下情况:
1.Oracle 数据库回退 在savepoint 之后运行的语句
2.Oracle数据库保留在ROLLBACK TO SAVEPOINT语句中指定的保存点,但所有后续保存点都将丢失。
3.Oracle数据库释放在指定保存点之后获取的所有表和行锁,但保留在保存点之前获取的所有数据锁。
事务仍然活跃,可以继续。
事务队列
根据情况,等待先前锁定的资源的事务在回滚到保存点后可能仍然被阻止。当事务被另一个事务阻塞时,它将阻塞事务本身排入队列,以便整个阻塞事务必须提交或回滚以使被阻止事务继续。
在表10-2所示的场景中,会话1回滚到在执行DML语句之前创建的保存点。但是,会话2仍然被阻止,因为它正在等待会话1事务完成。
--意思是,即便是回滚到一个点(行锁已经释放),已经等待锁的阻塞事务会继续等待事务的提交回滚。但是新的会话可以请求到行锁,更新这些行。
session1:
UPDATE employees
SET salary=7000
WHERE last_name=
'Banda';
savepoint after_banda_sal;
UPDATE employees
SET salary=12000
WHERE last_name=
'Greene';
--会话1在保存点前后锁住了2行
session2:
UPDATE employees
SET salary=14000
WHERE last_name=
'Greene';
--这个更新会被阻塞,因为session锁住了这行,所以session 2 不会开启事务
会话1
ROLLBACK
TO SAVEPOINT
after_banda_sal;
---会话1回滚到保存点,释放了Greene的行锁。但是表锁还没释放。在这个时候,会话2仍然会被会话1阻塞,因为会话2在会话1事务(未完成)队列之后。
session
UPDATE employees
SET salary=11000
WHERE last_name=
'Greene';
-新会话当前没有被锁,这个语句在session3中开启了新的事务
会话1提交
commit
--现在会话2进入事务队列在事务3之后。
事务的回滚
未提交事务的回滚将撤消对事务中的SQL语句执行的数据的任何更改。事务回滚后,事务中完成的工作的效果不再存在
在回滚整个事务时,不引用任何保存点,Oracle数据库将执行以下操作:
1.使用相关的undo段撤销事务中所有SQL 语句产生的所有变更
每个活动事务的事务表条目包含指向事务的所有undo数据(以相反的应用顺序)的指针。数据库从undo段读取数据,反转操作,然后标记应用的undo条目。因此,如果一个事务插入一行,那么回滚将会删除它。如果事务更新一行,则回滚会反转更新。如果事务删除一行,则回滚将重新插入。
2.释放事务持有的所有数据锁
3.擦除事务中的所有保存点
4.结束事务
回滚的持续时间是修改的数据量的时间函数。
事务提交
一个commit 结束当前事务 并使事务中所有的变更成为永久的。
事务提交时,会发生以下操作:
1.一个SCN为COMMIT 生成。
关联的undo表空间的内部事务表记录了事务已经提交的内容。事务对应的唯一SCN被分配并记录在事务表中。
2.LGWR 将log buffer中的剩余日志写入到 redo log中,并将事务SCN写入到 redolog。这个原子事件构成事务的提交。
3.Oracle 数据库释放行和表上持有的锁。
那些等待未提交事务的 用户可以继续工作
4.Oracle 数据库删除 savepoint
5.Oracle数据库执行提交清除。
如果包含提交事务中的数据的修改块仍在SGA中,并且如果没有其他会话正在修改它们,则数据库将从块中删除与锁相关的事务信息(ITL条目)。
理想情况下,COMMIT清理块,以便后续的SELECT不必执行此任务。如果特定行不存在ITL条目,则该行不会被锁定。如果某个特定行存在一个ITL条目,则它可能已被锁定,因此会话必须检查撤消段标头以确定此感兴趣的事务是否已提交。如果感兴趣的事务已提交,则会话将清除该块,从而生成重做。但是,如果COMMIT事先清除了ITL,则不需要检查和清除。
--但实际上,如果块被写入到磁盘,那么这些块需要下一次select的时候清理,也就是延时块清理。
注意:因为块清除生成redo,所以select可能会产生redo,从而导致在下一个检查点期间写入块。
6. Oralce 数据库标记事务完成
在一个事务commit之后,用户可以看到变更。
通常情况下,一个commit是很快速的操作,不管事务的大小。提交的速度不会随着事务中修改数据量的大小而增加。提交执行最长的部分是 LGWR物理磁盘I/O。然而,由于LGWR已经在后台逐步写入重做日志缓冲区的内容,因此减少了LGWR花费的时间。
默认行为是将LGWR同步写入在线redo,事务等待log buffer写到磁盘上然后返回用户一个提交。然后为了更低的事务提交延时,应用程序开发人员可以指定redo异步写入,以便事务无需等待redo写到磁盘上,可以立即返回commit(数据库层面也有一个快过期的参数控制)
事务Guard 概述
Transaction Guard是一种API,应用程序可以使用该API提供事务幂等性,这是数据库保留有保证的提交结果的能力,该结果指示事务是否已提交和完成。Oracle数据库为JDBC瘦,OCI,OCCI和ODP.Net提供了API。
可恢复错误是由外部系统故障引起的,与正在执行的应用程序会话逻辑无关。在前台进程,网络,节点,存储和数据库的计划内和计划外中断之后,都会发生可恢复的错误。如果中断中断了客户端应用程序和数据库之间的连接,则该应用程序会收到断开连接错误消息。连接断开时正在运行的事务称为运行中事务。
为了决定是重新提交事务还是将结果(已提交或未提交)返回给客户端,应用程序必须确定进行中事务的结果。在Oracle Database 12c之前,返回给客户端的提交消息不是持久的。检查事务并不能保证它在被检查后不会提交,从而允许重复事务和其他形式的逻辑损坏。例如,用户在线购买图书时可能会刷新Web浏览器,并且为同一本书收取两次费用。
事务guard的优势
从Oracle Database 12c开始,Transaction Guard为应用程序提供了一种工具,用于确定可恢复中断后正在进行的事务的状态。
使用Transaction Guard,应用程序可以确保事务执行不超过一次。例如,如果在线书店应用程序确定先前提交的提交失败,则该应用程序可以安全地重新提交。
Transaction Guard提供了一个最多执行一次的工具,以避免应用程序执行重复提交。Transaction Guard为每个事务提供已知结果。
Transaction Guard是Oracle数据库的核心功能。当掩盖最终用户的中断时,应用程序连续性将使用Transaction Guard。如果没有Transaction Guard,则应用程序在错误之后重试可能会导致重复的事务被提交。
Transaction Guard 如何工作
本节说明丢失提交消息的问题以及Transaction Guard如何使用逻辑事务ID解决该问题。
丢失commit 信息
在设计幂等性时,开发人员必须在提交commit语句后解决通信失败的问题。提交消息不会保留在数据库中,因此失败后将无法检索。
下图是客户端应用程序与数据库之间交互的高级表示。

在标准提交情况下,数据库将提交事务并向客户端返回成功消息。在图10-2中,客户端提交了一条commit语句,并收到一条消息,指出通信失败。发生这种类型的故障的原因有多种,包括数据库实例故障或网络中断。在这种情况下,客户端不知道事务的状态。
通信失败后,数据库可能仍在运行提交,并且不知道客户端已断开连接。检查事务状态不能保证活动的事务在被检查后不会提交。如果客户端由于此过期信息而重新发送提交,则数据库可能会重复该事务,从而导致逻辑损坏。
逻辑事务ID
Oracle数据库通过使用称为逻辑事务ID的全局唯一标识符来解决通信故障。
该ID包含会话首次连接时分配的逻辑会话号,以及每次会话提交或回滚时都会更新的运行提交号。从应用程序的角度来看,逻辑事务ID唯一地标识上一次失败的会话提交的最后一个数据库事务。
对于来自提交了一个或多个事务的客户端的每次往返,数据库都会存储逻辑事务ID。对于每个提交数据的往返,此ID可以为应用程序和数据库之间的交互提供事务幂等性。
最多一次协议通过要求数据库执行以下操作来启用对提交结果的访问:
在商定的重试保留期中保留逻辑事务ID
提交时保持逻辑事务ID
事务运行时,数据库和客户端都持有逻辑事务ID。从身份验证时,从连接池借用时以及在从客户端驱动程序执行一次或多项提交操作的每次往返中,数据库都会为客户端提供逻辑事务ID。
在应用程序确定可恢复错误之后的最后一个事务的结果之前,应用程序使用Java,OCI,OCCI或ODP.Net API获取客户端保存的逻辑事务ID。然后,应用程序使用逻辑事务ID调用PL SQL过程DBMS_APP_CONT.GET_LTXID_OUTCOME,以确定最后一次提交的结果:已提交(是或否)和已完成用户调用(是或否)。
使用Transaction Guard时,应用程序可以在错误可恢复且会话上的最后一个事务尚未提交时重播事务。当最后一个事务已提交并且用户调用已完成时,应用程序可以继续。应用程序可以使用Transaction Guard将已知结果返回给客户端,以便客户端可以决定要采取的下一个操作。
例子:
Transaction Guard使用逻辑事务ID来保存COMMIT语句的结果,从而确保该事务存在已知结果。

在图10-3中,数据库通知应用程序事务是否已提交以及上次用户调用是否完成。然后,应用程序可以将结果返回给最终用户。可能是:
如果提交了事务并且完成了用户调用,则应用程序可以将结果返回给最终用户并继续。
如果事务已提交但用户调用未完成,则应用程序可以将结果返回警告并返回给最终用户。示例包括丢失的绑定或丢失的已处理行数。一些应用程序依赖于额外的信息,而另一些则不依赖。
如果未提交用户call,则应用程序可以将此信息返回给最终用户,或安全地重新提交。该协议是有保证的。当提交状态返回false时,将阻止后一次提交。
自治事务概述
自治事务是一个独立的事务,可以从称为主事务的另一个事务调用。您可以暂停调用事务,执行SQL操作并在自治事务中提交或撤销它们,然后恢复调用事务。
自动事务对于必须独立执行的操作很有用,无论调用事务是提交还是回滚。例如,在股票购买交易中,您想要提交客户数据,而不管整体股票购买是否通过。此外,即使整个事务回滚,您也想将错误消息记录到调试表。
自治事务具有以下特点:
1.自治事务不会看到主事务所做的未提交的更改,并且不与主事务共享锁或资源。
2.在提交自治事务时,自治事务中的变更对其他事务是可见的。因此,用户可以访问更新的信息,而不必等待主事务提交。
3.自治事务可以开始其他自治事务。除了资源限制外,对于可以调用多少级别的自治事务没有限制。
在PL / SQL中,自治事务在自治范围内执行,这是一个用语法 AUTONOMOUS_TRANSACTION标记的例程。在这种情况下,例程包括顶级匿名PL / SQL块和PL / SQL子程序和触发器。编译指令是指示编译器执行编译选项的指令。编译指示AUTONOMOUS_TRANSACTION指示数据库执行时,该过程将作为独立于其父事务的新自主事务执行。
AUTONOMOUS_TRANSACTION
表示该语句是编译指令(编译器指令)。编译器在编译时处理,而不是在运行时处理。他们将信息传递给编译器。
您可以将此编译指令应用于:
顶级(非嵌套)匿名PL / SQL块
本地,独立和打包的功能和过程
SQL对象类型的方法
数据库触发器
您不能将此编译指示应用于整个包或整个对象类型。相反,您可以将pragma应用于每个打包的子程序或对象方法。
您可以在声明部分的任何地方编写指令码。为了可读性,请在该部分的顶部编写代码。
例如:
declare
PRAGMA AUTONOMOUS_TRANSACTION;
一旦开始,自主交易是完全独立的。它与主事务不共享锁,资源或提交依赖关系。您可以记录事件,增加重试计数器等,即使主事务回滚。
与常规触发器不同,自治触发器可以包含事务控制语句(如COMMIT和ROLLBACK),并且可以通过EXECUTE IMMEDIATE语句发出DDL语句(如CREATE和DROP)。
当自主交易提交时,自治交易所做的更改对其他交易可见。当主要事务恢复时,更改也将变得可见,但只有当其隔离级别设置为READ COMMITTED(默认值)时。如果将主事务的隔离级别设置为SERIALIZABLE,那么其自治事务所做的更改在主事务恢复时将不可见。
在主事务中,回滚到自主子程序调用之前的保存点不会回滚自治事务。记住,自主交易完全独立于主要交易。
如果自治事务尝试访问主事务持有的资源(直到自治例程退出才能恢复),则可能会发生死锁。Oracle在自治事务中引发异常,如果异常未处理,则它将回滚。
如果您尝试退出活动的自治事务而不提交或回滚,Oracle会引发异常。如果异常未处理,或由于某些其他未处理的异常而导致事务结束,则事务将回滚。
当您进入自治例程的可执行部分时,主程序将暂停。当您退出自治程序时,主程序恢复。
下图显示了控制如何从主例程(MT)流向自主例程,然后又返回。主例程是proc1,自治例程是proc2。自主例程可以在控制权返回主例程之前提交多个事务(AT1和AT2)

当您进入自治例程的可执行部分时,主例程将挂起。退出自治例程后,主例程将恢复。
在图10-4中,proc1内部的COMMIT不仅将其自身的工作永久化,而且还将其会话中执行的所有工作永久化。但是,proc2中的COMMIT仅使proc2事务中执行的工作永久化。因此,事务AT1和AT2中的COMMIT语句对MT事务没有影响。
分布式事务
分布式数据库是分布式系统中的一组数据库,可以将应用程序显示为单个数据源。分布式事务是包含一个或多个使用称为数据库链接的模式对象来更新分布式数据库的两个或多个不同节点上的数据的语句的事务。数据库链接描述了一个数据库实例如何登录到另一个数据库实例。
与本地数据库上的事务不同,分布式事务会更改多个数据库上的数据。因此,分布式事务处理更复杂,因为数据库必须协调将事务中的更改提交或回退为原子单元。整个事务必须提交或回滚。即使发生网络或系统故障,Oracle数据库也必须通过网络协调事务控制并维护数据的一致性。
二阶段 提交
两阶段提交机制保证参与分布式事务的所有数据库都提交或全部撤销事务中的语句。该机制还保护由完整性约束,远程过程调用和触发器执行的隐式DML。
在多个数据库之间的两阶段提交中,一个数据库协调分布式事务。启动节点称为全局协调器。协调者询问其他数据库是否准备提交。如果任何数据库使用no响应,则整个事务将回滚。如果所有数据库都输入“是”,则协调器会广播一条消息,使提交在每个数据库上永久保留。
两阶段提交机制对发布分布式事务的用户是透明的。事实上,用户甚至不知道事务是分发的。表示事务结束的COMMIT语句自动触发两阶段提交机制。在数据库应用程序的主体中包含分布式事务不需要编码或复杂语句语法。
参考:http://docs.oracle.com/cd/E11882_01/server.112/e25494/ds_txns.htm#ADMIN12222
In-Doubt Transactions
当两阶段提交被任何类型的系统或网络故障中断时,都会发生无疑的分布式事务。例如,两个数据库向协调数据库报告它们准备提交,但协调数据库实例在收到消息后立即失败。准备承诺的两个数据库现在在等待通知结果的同时暂停。
恢复器(RECO)后台进程自动解决无限分布式事务的结果。在修复失败并重新建立通信后,每个本地Oracle数据库的RECO进程自动在所有相关节点上一致地提交或回滚任何无疑的分布式事务。
如果发生长期故障,Oracle数据库将使每个本地管理员能够手动提交或撤销任何由于失败而导致的疑难的分布式事务。此选项使本地数据库管理员能够释放由于长期故障而无限期保留的锁定资源。
如果数据库必须恢复到过去的时间,那么数据库恢复工具使其他站点的数据库管理员可以将其数据库返回到较早的时间点。此操作可确保全局数据库保持一致。
========
使用DBLINK的查询会带一个事务,而且是一个distributed transaction(分布式事务)
应用端大量用到DBLINK查询会占用远程数据库的session。本地的session没有释放掉或者出现异常信息,就会导致远程数据库的session大量占用。时间久了就会报ORA-01555。
对于应用端中使用dblink之后,需要显示的用alter session close database DBLINK_NAME来关闭远程数据库的session连接,执行前必须先commit,否则会出现ORA-02080错误或者其他错误。
--close dblink method 1 :
SQL> commit;
SQL> ALTER SESSION CLOSE DATABASE LINK DBLINK_NAME;
in plsql used:
execute immediate ' ALTER SESSION CLOSE DATABASE LINK DBLINK_NAME';
or
--close dblink method 2 :
SQL> commit;
SQL> begin
dbms_session.close_database_link('DBLINK_NAME');
end;
/




