为什么只从数据库视图中选择时会获得一个打开的事务?

Jam*_*man 8 sql oracle plsql oracle11g plsqldeveloper

如果我在pl/sql开发人员中对数据库表执行一个简单的select语句,我会得到一组标准的结果,如我所料.

最近,我从一个恰好从视图中选择的存储过程粘贴了一个查询,并注意到一个事务似乎保持打开状态.PL/SQL开发人员可以使用回滚和提交选项.

对其他开发人员的调查显示,这似乎影响了一些但不影响其他人,这导致我怀疑PL/SQL Developer设置.

为什么会这样呢?视图itelf有一个DBLink到另一个数据库,但我不希望这会产生任何影响.

有什么想法吗?

Luk*_*ard 19

与您的期望相反,看起来数据库链接开放交易的来源.在PL/SQL Developer中对远程表运行SELECT查询之前,我注意到了这样的行为.

引用Tom Kyte(来源):

分布式东西启动事务"以防万一".

编辑:'任何SQL语句在Oracle中启动事务'?不,它没有,这是一个演示.此演示使用数据字典视图V $ TRANSACTION,其中列出了活动事务.这都在我的本地Oracle XE数据库上运行,该数据库除了我之外没有其他用户连接到它.

我们将在演示期间使用下表.它只包含一列:

SQL> desc test;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 A                                                  NUMBER(38)

SQL> select count(*) from v$transaction;

  COUNT(1)
----------
         0

目前没有活跃的交易.让我们对这个表运行一个SQL查询:

SQL> select * from test;

         A
----------
         2

SQL> select count(*) from v$transaction;

  COUNT(1)
----------
         0

仍然没有活跃的交易.现在让我们做一些会启动交易的事情:

SQL> insert into test values (1);

1 row created.

SQL> select count(*) from v$transaction;

  COUNT(1)
----------
         1

正如所料,我们现在有一个活跃的交易.

SQL> commit;

Commit complete.

SQL> select count(*) from v$transaction;

  COUNT(1)
----------
         0

提交交易后,它不再有效.

现在,让我们创建一个数据库链接.我正在使用Oracle XE,以下内容创建了一个从我的Oracle XE实例返回自身的数据库链接:

SQL> create database link loopback_xe connect to user identified by password using 'XE';

Database link created.

现在让我们看看当我们通过数据库链接从表中选择时会发生什么:

SQL> select count(*) from v$transaction;

  COUNT(1)
----------
         0

SQL> select * from test@loopback_xe;

         A
----------
         2
         1

SQL> select count(*) from v$transaction;

  COUNT(1)
----------
         1

如您所见,只需从远程表中选择即可打开一个事务.

我不确定在这里提交或回滚到底是什么,但我不得不承认不知道分布式事务的来龙去脉,答案可能就在其中.


小智 3

任何SQL 语句都会在 Oracle 中启动一个事务。

从手册中:

事务从第一个可执行 SQL 语句开始。事务在提交或回滚时结束,无论是使用 COMMIT 或 ROLLBACK 语句显式提交还是回滚,或者在发出 DDL 语句时隐式提交或回滚。[...]可执行SQL语句是生成对实例的调用的SQL语句,包括DML和DDL语句

最有可能的是那些没有看到这一点的人正在自动提交模式下运行,其中由语句启动的事务在语句完成后立即提交。

其他人声称 aSELECT不是 DML,但手册再次明确指出

数据操作语言 (DML) 语句查询或操作现有架构对象中的数据。它们使您能够:

   * 从一个或多个表或视图中检索或获取数据 (SELECT)
   * 将新数据行添加到表或视图中 (INSERT)
[...]

  • @a_horse_with_no_name:并非每个 SQL 语句都会启动事务。请参阅我的(更新的)答案中的演示。 (6认同)
  • @Porquoi:嗯......Oracle需要有“某种”事务才能支持读取一致性。当将会话设置为可序列化时,V$TRANSACTION 实际上会显示一个简单 SELECT 语句的条目。因此,READ COMMITTED 模式下的 SELECT 的“事务”可能非常“弱”,以至于没有记录在 V$TRANSACTION 中 (2认同)