Oracle - есть ли способ просмотреть незафиксированные изменения в конкретной таблице?

24

В настоящее время я отлаживаю пакетный процесс, который выполняет много операторов DML, но не выполняет коммит сразу. Было бы неплохо иметь возможность просматривать «ожидающие» изменения из другого сеанса, пока транзакция не зафиксирована. Это возможно?

Пример:

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

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

...other DML statements....

commit;
contactmatt
источник
Существует несколько способов сделать это. Например, операторы SQL здесь могут решить: ducquoc.wordpress.com/2012/07/14/oracle-uncommited-changes удачи,

Ответы:

18

Существует несколько разных подходов в зависимости от деталей вашего пакетного процесса и причин, по которым вы пытаетесь просмотреть незавершенные изменения.

1) Oracle Workspace Manager - это инструмент, изначально разработанный для того, чтобы позволить людям, разрабатывающим пространственные приложения, иметь эквивалент чрезвычайно длительных транзакций (т. Е. Транзакций, которые могут потребовать нескольких дней или недель, чтобы люди выяснили, где запустить конвейер в одной транзакции). ). Ваш пакетный процесс может создать новое рабочее пространство (что по логике похоже на создание новой транзакции), вносить любые изменения, которые он хотел бы в этом рабочем пространстве, при фиксации всякий раз, когда он захочет. В отдельном сеансе вы не увидите никаких зафиксированных изменений, пока не войдете в рабочую область пакетного процесса. Когда пакетный процесс завершен, он может слить свое рабочее пространство обратно в рабочее рабочее пространство, что является эквивалентом совершения транзакции.

2) Пакет DBMS_XA может использоваться, чтобы позволить вам «передать» транзакцию из одного сеанса в другой и позволить одному сеансу подключиться к транзакции, запущенной другим сеансом. Это довольно непонятный пакет для использования, но в последнее время был хороший пример его использования в PL / SQL Challenge (вам может понадобиться бесплатная учетная запись для доступа к нему).

3) Если вы просто пытаетесь увидеть состояние пакетного процесса, а не фактические данные, пакетный процесс может записывать информацию журнала, используя автономные транзакции, которые вы затем могли бы запросить из другого сеанса. Или вы можете использовать пакет DBMS_APPLICATION_INFO, чтобы ваше приложение обновляло различные атрибуты в V $ SESSION и / или V $ SESSION_LONGOPS, чтобы вы могли отслеживать состояние загрузки из другого сеанса.

Джастин Кейв
источник
10

редактировать: это было написано до выяснения вопроса

Вы можете использовать ретроспективные запросы, чтобы увидеть таблицу без ваших собственных незафиксированных данных.

Рассмотреть возможность:

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
Винсент Малграт
источник
2
@jack: неясно, хочет ли ОП видеть незафиксированные данные вне сеанса (псевдокрипт может быть в одном сеансе). Мой ответ будет работать только для того, чтобы увидеть собственные ожидающие изменения в таблице.
Винсент Малграт
ты прав, прости. Отличный ответ.
Джек Дуглас
8

Да, LogMiner может сделать это. На самом деле, если вы хотите только совершенные транзакции, вы должны специально фильтровать вывод! И есть TABLE_NAMEв V$LOGMINER_CONTENTS, то, как вы будете выглядеть в одной таблице.

Gaius
источник
8

У 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 обработанных строк независимо от успеха длинного действия. Если вам нужна точная копия данных, чтобы увидеть, как они работают, я предлагаю создать копию таблицы и вызвать процедуру, которая будет дублировать данные (процедура является автономной транзакцией). Затем постучите в ноль данных. (Нет необходимости в дублировании.)

Кроме того, если это делается для целей отладки, я предлагаю исключить или радикально уменьшить необходимость такой регистрации, когда что-то проверено. И, как всегда, тестируйте, тестируйте, тестируйте на своей собственной системе, чтобы проверить, как все будет работать. (См. Комментарий Найла для хорошего примера того, как ведение журнала может существенно повлиять на производительность.)

(Наконец, потому что я не упомянул об этом раньше: остерегайтесь автономных транзакций. Полностью поймите их перед реализацией и не используйте их «только потому, что». Они могут быть использованы миллионами способов неправильно (скажем, например, чтобы попытаться избежать ошибки изменения в триггере), поэтому всегда лучше найти альтернативы, если это возможно. Если вы не можете, тогда действуйте с осторожностью. Ведение журнала во время длительных операций всегда было одним из случаев, когда это довольно безопасно (игнорирование проблемы с производительностью), но не спешите применять его для других целей, не зная последствий.)

Керри Шоттс
источник
1
Предостережения в конце этого предложения более подробно рассматриваются в моем длинном ответе (с кодом) на orawin.info/blog/2011/09/06/advice-from-the-internet . Короче говоря, принятие этого подхода может серьезно и негативно повлиять на код, который уже работает медленно.
Найл Личфилд
1
@Niall Litchfield, Как всегда, когда вы берете советы из интернета, всегда нужно тестировать, тестировать, тестировать. Когда упомянуто, что автономная транзакция не влияет на транзакцию, я имел в виду тот факт, что она не совершает или ROLLsBACK вашей текущей транзакции; следовательно, в ЛОГИЧЕСКОМ смысле это ничего не делает для вашей текущей транзакции. Да, конечно, Oracle делает что-то закулисное, чтобы заставить вещи работать, что может означать проблемы с производительностью, с точки зрения только транзакции, автономная транзакция не мешает состоянию моей текущей транзакции.
Керри Шоттс
@Niall Litchfield, Все это говорит о том, что у автономных транзакций есть своя собственная доля проблем (одна из которых заключается в том, что люди пытаются использовать их, чтобы обойти изменяющуюся таблицу), и поэтому я рекомендую их с осторожностью и осторожностью, и ТОЛЬКО с пониманием того, что происходит.
Керри Шоттс
3

Недоступно в 10g, но DBMS_XA может разрешить транзакции пересекать несколько сеансов. Используя это, вторая сессия может увидеть, что происходит в транзакции

Gary
источник
3

В дополнение к другой информации здесь, некоторые дополнительные способы отправки информации о незафиксированной транзакции могут заключаться в отправке электронного письма или записи в текстовый файл.

Ли Риффель
источник