Подтвердить что ты не робот

Oracle: как узнать, ожидает ли транзакция?

Я ищу способ узнать, имеются ли в текущем сеансе операторы INSERT, UPDATE или DELETE без ограничений. Один из способов - проверить v $lock с текущим sid, но для этого требуется доступ для чтения к блокировке v $, что является проблемой, если администратор базы данных не хочет ее предоставлять. Любые другие способы (кроме отслеживания всех команд базы данных, выданных приложением)?

4b9b3361

Ответ 1

вы можете проверить, есть ли в вашем сеансе строка в V$TRANSACTION (очевидно, для этого требуется привилегия чтения):

SQL> SELECT COUNT(*)
       FROM v$transaction t, v$session s, v$mystat m
      WHERE t.ses_addr = s.saddr
        AND s.sid = m.sid
        AND ROWNUM = 1;

  COUNT(*)
----------
         0

SQL> insert into a values (1);

1 row inserted

SQL> SELECT COUNT(*)
       FROM v$transaction t, v$session s, v$mystat m
      WHERE t.ses_addr = s.saddr
        AND s.sid = m.sid
        AND ROWNUM = 1;

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

SQL> commit;

Commit complete

SQL> SELECT COUNT(*)
       FROM v$transaction t, v$session s, v$mystat m
      WHERE t.ses_addr = s.saddr
        AND s.sid = m.sid
        AND ROWNUM = 1;

  COUNT(*)
----------
         0

Ответ 2

Это запрос, который я обычно использую,

select s.sid
      ,s.serial#
      ,s.username
      ,s.machine
      ,s.status
      ,s.lockwait
      ,t.used_ublk
      ,t.used_urec
      ,t.start_time
from v$transaction t
inner join v$session s on t.addr = s.taddr;

Ответ 6

Самое простое и надежное решение - попытаться запустить транзакцию и увидеть ее, если она будет успешной. Если какой-то код уже начал транзакцию, но еще не выпустил ни один DML, то представление V $ TRANSACTION ничего не покажет.

В этом примере ниже я обрабатываю исключение, чтобы повысить пользовательскую ошибку приложения. Чтобы отложить до существующего обработчика исключений, просто сделайте SET TRANSACTION, а затем немедленно COMMIT, чтобы отменить его.

DECLARE
    transaction_in_progress EXCEPTION;
    PRAGMA EXCEPTION_INIT(transaction_in_progress, -1453);
BEGIN
    SET TRANSACTION NAME 'CHECK_FOR_TRANSACTION_ALREADY_SET';
    COMMIT; -- end transaction
EXCEPTION
    WHEN transaction_in_progress THEN
        RAISE_APPLICATION_ERROR(-20000,'Transaction is already in progress');
END;
/

Ответ 7

Мэтью Уотсон может быть изменен для использования в RAC

select t.inst_id 
       ,s.sid
      ,s.serial#
      ,s.username
      ,s.machine
      ,s.status
      ,s.lockwait
      ,t.used_ublk
      ,t.used_urec
      ,t.start_time
from gv$transaction t
inner join gv$session s on t.addr = s.taddr;