我目前正在通过批处理过程进行调试,该批处理过程执行许多DML语句,但不会立即进行提交。能够在未提交事务的情况下查看另一个会话中的“待处理”更改将是很好的。

示例:

Insert into table myTable (col1, col2) values ("col1", "col2");

--Somehow view the pending transaction maybe by system view?....

...other DML statements....

commit;


评论

有多种方法可以做到这一点。例如,此处的SQL语句可以解决:ducquoc.wordpress.com/2012/07/14/oracle-uncommited-changes祝您好运,

#1 楼

有几种不同的方法,具体取决于批处理过程的详细信息以及尝试查看未提交的更改的原因。
1)Oracle Workspace Manager是一种最初旨在允许人们进行开发的工具空间应用程序具有与极其长时间运行的事务等效的功能(即,可能需要数天或数周的人工才能确定一次事务中在何处运行管道的事务)。您的批处理过程可以创建一个新的工作空间(在逻辑上就像创建一个新的事务一样),并在需要时进行提交时在该工作空间中进行所需的任何更改。在单独的会话中,直到进入批处理流程的工作空间,您都看不到任何已提交的更改。批处理过程完成后,可以将其工作空间合并回活动工作空间,这相当于提交事务。

2)DBMS_XA包可用于允许您将事务从一个会话“切换”到另一个会话,并允许一个会话连接到另一个会话启动的事务。这是一个非常晦涩的软件包,但是最近在PL / SQL Challenge中有一个很好的使用示例(您可能需要一个免费帐户才能访问它)。

3)如果您只是想查看批处理过程的状态而不是查看实际数据,则批处理过程可以使用自主事务编写日志记录信息,然后您可以从另一个会话中查询。或者,您可以使用DBMS_APPLICATION_INFO包使您的应用程序更新V $ SESSION和/或V $ SESSION_LONGOPS中的各种属性,以便可以监视来自另一个会话的负载状态。

#2 楼

编辑:这是在问题明确之前编写的。

您可以使用闪回查询来查看没有您自己未提交的数据的表。

考虑者:

SQL> CREATE TABLE my_table
  2  AS SELECT ROWNUM ID FROM dual CONNECT BY LEVEL <= 5;

Table created

SQL> INSERT INTO my_table VALUES (6);

1 row inserted


要查看我的交易表和其他人看到的表之间的区别,我可以发出:

SQL> SELECT * FROM my_table
  2  MINUS
  3  SELECT * FROM my_table AS OF TIMESTAMP (systimestamp);

        ID
----------
         6


评论


@jack:尚不清楚OP是否希望在其会话之外查看未提交的数据(伪脚本可能在单个会话中)。我的答案只会在看到自己对表的未完成修改时起作用。

– Vincent Malgrat
2011年5月30日20:15

你说得对,对不起。好答案。

–杰克·道格拉斯(Jack Douglas)
2011年5月31日4:27



#3 楼

是的-LogMiner可以做到这一点。实际上,如果您只想要提交的事务,则必须专门过滤输出!在TABLE_NAME中有V$LOGMINER_CONTENTS,这就是您查看单个表的方式。

#4 楼

Oracle没有的是读未提交隔离模式。换句话说,您将无法在另一笔交易中查询未提交的数据。小心)

#5 楼

没有直接的方法。您要么必须解析日志(如另一个答案中所述),要么使用其他方法来查看长时间运行的过程中发生的事情。

我个人建议使用自治事务来启用此功能-不涉及事务本身,而是作为一种日志记录机制,可让您了解正在发生的事情。例如,您可能有PROCEDURE LONG_ACTION调用PROCEDURE WRITE_LOG_ENTRY(定义为自主事务),该调用会将VARCHAR2写入另一个表。自主事务不会干扰您的当前事务(从逻辑的角度;要注意对性能的潜在影响),因此无论当前事务中的COMMIT还是ROLLBACK,您都可以通过日志记录条目查看正在发生的情况。就是说,您可以使用一个庞大的DML语句来做到这一点;您必须使用循环。

考虑:

TABLE LOG_ENTRIES defined as
    activity_date  date,
    log_entry varchar2(2000)

TABLE BIG_JOB (definition doesn't really matter)

PROCEDURE WRITE_LOG_ENTRY
                        ( str VARCHAR2 )
IS
    PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    INSERT INTO LOG_ENTRIES VALUES ( SYSDATE, str );
    COMMIT;
END;

PROCEDURE LONG_ACTION IS
    c NUMBER;
BEGIN
    FOR r IN ( SELECT * FROM BIG_JOB )
    LOOP
       c := c + 1;
       UPDATE BIG_JOB z
          SET fld = hairy_calculation
        WHERE z.rowid = r.rowid;
       IF MOD(c,500) = 0 THEN
           WRITE_LOG_ENTRY ( c || ' rows processed.' );
       END IF;
    END LOOP;
    COMMIT;
END;


基于以上内容,每500个日志条目中就有一个无论长操作是否成功,都会处理行。如果您需要数据的精确重复才能正常工作,我建议制作一个重复表并调用一个将复制数据的过程(该过程是一个自主事务)。然后事后核对数据。 (无需重复。)

此外,如果这是出于调试目的,我建议在测试完毕后删除或大幅减少此类日志记录的需求。与往常一样,在您自己的系统上进行测试,测试和测试,以验证事情的工作方式。 (有关日志如何严重影响性能的一个很好的例子,请参见Niall的评论。)

(最后,因为我之前没有提到它:当心自主交易。在实施之前要充分理解它们,不要仅仅因为“使用”而使用它们。它们可能被错误地以百万种方式使用(例如,对于ATTEMPT,避免在触发器中发生变异错误),因此,如果可能的话,最好总是找到替代方法。如果不能,则请谨慎行事。长期运行ops期间的日志记录始终是相当安全的一种情况(性能问题),但不要在不知道后果的情况下急于将其应用于其他用途。)

评论


我在orawin.info/blog/2011/09/06/advice-from-the-internet上的长时间回复(带有代码)中进一步探讨了该建议结尾的警告。简而言之,采用这种方法可能会对已经很慢的代码产生严重和不利的影响。

–尼尔·利奇菲尔德
2011年9月6日上午11:23

@Niall Litchfield,和往常一样,当从互联网上征求意见时,应该始终进行测试,测试和测试。当提到自主交易不会影响交易时,我指的是它既不会提交也不会回滚您当前的交易;因此,从逻辑上讲,它对您当前的交易没有任何作用。是的,当然,Oracle在幕后做了一些事情才能使事情正常运行,这可能意味着性能问题,从仅事务的角度来看,自主事务不会妨碍我当前事务的状态。

–凯瑞·肖茨(Kerri Shotts)
2011-09-10 16:55

@Niall Litchfield,总而言之,自主交易有其自身的部分问题(其中之一恰好是人们试图使用它们来解决变异表的问题),因此我建议您谨慎谨慎地使用它们,并且仅了解发生了什么。

–凯瑞·肖茨(Kerri Shotts)
2011-09-10 16:55

#6 楼

在10g中不可用,但是DBMS_XA可以允许事务跨多个会话。使用第二个会话,可以看到事务中发生了什么

#7 楼

除了此处的其他信息之外,发送有关未提交的交易的信息的一些其他方法是发送电子邮件或写入文本文件。