it-swarm.it

Oracle: un modo per visualizzare le modifiche senza commit a una determinata tabella?

Attualmente sto eseguendo il debug attraverso un processo batch che esegue molte istruzioni DML, ma non esegue immediatamente un commit. Sarebbe bello poter visualizzare le modifiche "in sospeso" da un'altra sessione mentre la transazione non è impegnata. È possibile?

Esempio:

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

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

...other DML statements....

commit;
24
contactmatt

Esistono diversi approcci a seconda dei dettagli del processo batch e del motivo per cui stai provando a visualizzare le modifiche non impegnate.

1) Oracle Workspace Manager è uno strumento che è stato originariamente progettato per consentire alle persone che sviluppano applicazioni spaziali di avere l'equivalente di transazioni di lunga durata (ad esempio transazioni che potrebbero richiedere più giorni o settimane in cui gli umani capiscono dove per eseguire una pipeline in una transazione). Il processo batch potrebbe creare un nuovo spazio di lavoro (che è logicamente come la creazione di una nuova transazione), apportare le modifiche che vorrebbe in quell'area di lavoro mentre eseguiva il commit ogni volta che lo desiderava. In una sessione separata, non vedresti nessuna delle modifiche impegnate fino a quando non entri nell'area di lavoro del processo batch. Al termine del processo batch, è possibile unire nuovamente l'area di lavoro con l'area di lavoro live che equivale a eseguire una transazione.

2) pacchetto DBMS_XA può essere utilizzato per consentire di "distribuire" una transazione da una sessione all'altra e per consentire a una sessione di connettersi a una transazione avviata da un'altra sessione. Questo è un pacchetto piuttosto oscuro da usare, ma c'è stato un bell'esempio di utilizzo in sfida PL/SQL (potrebbe essere necessario un account gratuito per accedervi) di recente.

3) Se stai solo cercando di vedere lo stato del processo batch piuttosto che vedere i dati effettivi, il processo batch può scrivere informazioni di registrazione utilizzando transazioni autonome che potresti quindi interrogare da un'altra sessione. In alternativa, è possibile utilizzare pacchetto DBMS_APPLICATION_INFO per fare in modo che l'applicazione aggiorni vari attributi in V $ SESSION e/o V $ SESSION_LONGOPS in modo da poter monitorare lo stato del carico da un'altra sessione.

18
Justin Cave

modifica: questo è stato scritto prima che la domanda fosse chiarita

È possibile utilizzare le query di flashback per visualizzare la tabella senza i dati propri non sottoposti a commit.

Prendere in considerazione:

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

Per vedere la differenza tra la tabella con la mia transazione e la tabella vista da altri, potrei emettere:

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

        ID
----------
         6
10
Vincent Malgrat

Cosa Oracle non ha una modalità di isolamento senza commit di lettura . In altre parole, non sarà possibile eseguire query su dati non impegnati in un'altra transazione.

Ci sono modi per ottenere informazioni da una transazione di lunga durata - una non menzionata finora è transazioni autonome (che dovrebbe essere usata con cautela)

Sì - LogMiner può farlo. Infatti, se desideri solo transazioni impegnate, devi specificamente filtro l'output! E c'è TABLE_NAME in V$LOGMINER_CONTENTS, è così che guarderesti un singolo tavolo.

8
Gaius

Non esiste un metodo diretto; dovrai analizzare i registri (come menzionato in un'altra risposta) o utilizzare metodi alternativi per vedere cosa sta succedendo in un processo a lungo termine.

Personalmente, suggerisco di utilizzare transazioni autonome per abilitare questa funzione, non sulla transazione stessa, ma come meccanismo di registrazione che ti consente di sapere cosa sta succedendo. Ad esempio, è possibile che PROCEDURE LONG_ACTION chiami PROCEDURE WRITE_LOG_ENTRY (definita come transazione autonoma) che scriva un VARCHAR2 su un'altra tabella. Le transazioni autonome NON interferiscono con la transazione corrente (dal punto di vista LOGICO; attenzione ai potenziali impatti sulle prestazioni) e quindi è possibile vedere cosa sta succedendo tramite le voci di registrazione indipendentemente da COMMIT o ROLLBACK nella transazione corrente. Detto questo, puoi farlo con una massiccia istruzione DML; dovresti usare un ciclo.

Prendere in considerazione:

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;

Dato quanto sopra, otterrai una voce di registro per ogni 500 righe elaborate indipendentemente dal successo dell'azione lunga. Se hai bisogno di un duplicato esatto dei dati per vedere come funziona, ti suggerisco di creare una tabella duplicata e di chiamare una procedura che duplicherà i dati (la procedura è una transazione autonoma). Dopodiché, annulla i dati. (Non è necessario duplicare.)

Inoltre, se questo è a scopo di debug, suggerisco di rimuovere o ridurre drasticamente la necessità di tale registrazione quando le cose sono state testate. E, come sempre, test, test, test sul proprio sistema per verificare come funzioneranno le cose. (Vedi il commento di Niall per un buon esempio di come la registrazione può influenzare drasticamente le prestazioni.)

(Infine, perché ho dimenticato di menzionarlo prima: attenzione alle transazioni autonome. Comprenderle completamente prima dell'implementazione e non utilizzarle "solo perché". Possono essere utilizzate in modo errato in milioni di modi (ad esempio, TENTARE di evitare un errore mutato in un trigger), quindi è sempre meglio trovare alternative, se possibile. Se non è possibile, procedere con cautela. La registrazione durante operazioni a lungo termine è sempre stata un caso in cui è abbastanza sicuro (ignorando problemi di prestazioni), ma non correre per applicarlo ad altri usi senza conoscerne le conseguenze.)

5
Kerri Shotts

Non disponibile in 10 g, ma DBMS_XA può consentire a una transazione di attraversare più sessioni. Usandolo la seconda sessione può vedere cosa sta succedendo nella transazione

3
Gary

Oltre alle altre informazioni qui, alcuni modi aggiuntivi per inviare informazioni su una transazione non impegnata sarebbe quello di inviare un'e-mail o scrivere su un file di testo.

3
Leigh Riffel