web-dev-qa-db-fra.com

Oracle - Une façon de visualiser les modifications non validées dans une table particulière?

Je suis en train de déboguer à travers un processus par lots qui fait beaucoup d'instructions DML, mais ne fait pas de commit tout de suite. Ce serait bien de pouvoir voir les changements "en attente" d'une autre session alors que la transaction n'est pas validée. Est-ce possible?

Exemple:

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

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

...other DML statements....

commit;
24
contactmatt

Il existe différentes approches en fonction des détails de votre traitement par lots et des raisons pour lesquelles vous essayez d'afficher les modifications non validées.

1) Oracle Workspace Manager est un outil qui a été initialement conçu pour permettre aux personnes développant des applications spatiales d'avoir l'équivalent de transactions extrêmement longues (c'est-à-dire des transactions qui peuvent nécessiter plusieurs jours ou semaines d'humains pour déterminer où pour exécuter un pipeline en une seule transaction). Votre processus par lots pourrait créer un nouvel espace de travail (ce qui est logiquement comme la création d'une nouvelle transaction), apporter les modifications souhaitées dans cet espace de travail tout en validant à tout moment. Dans une session distincte, vous ne verrez aucune des modifications validées tant que vous ne serez pas entré dans l'espace de travail du traitement par lots. Une fois le traitement par lots terminé, il pourrait fusionner son espace de travail dans l'espace de travail actif, ce qui équivaut à valider une transaction.

2) Le package DBMS_XA peut être utilisé pour vous permettre de "transférer" une transaction d'une session à une autre et pour permettre à une session de se connecter à une transaction démarrée par une autre session. C'est un paquet assez obscur à utiliser, mais il y avait un bel exemple d'utilisation dans le PL/SQL Challenge (vous pourriez avoir besoin d'un compte gratuit pour y accéder) récemment.

3) Si vous essayez simplement de voir l'état du processus par lots plutôt que de voir les données réelles, le processus par lots peut écrire des informations de journalisation à l'aide de transactions autonomes que vous pouvez ensuite interroger à partir d'une autre session. Ou vous pouvez utiliser le package DBMS_APPLICATION_INFO pour que votre application mette à jour divers attributs dans V $ SESSION et/ou V $ SESSION_LONGOPS afin que vous puissiez surveiller l'état de la charge à partir d'une autre session.

18
Justin Cave

modifier: ceci a été écrit avant que la question ne soit clarifiée

Vous pouvez utiliser des requêtes flashback pour voir le tableau sans vos données propres non engagées.

Considérer:

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

Pour voir la différence entre la table avec ma transaction et la table vue par d'autres, je pourrais émettre:

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

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

Ce qu'Oracle ne possède pas est un mode d'isolation non engagé en lecture . En d'autres termes, vous ne pourrez pas interroger les données non validées dans une autre transaction.

Il existe des moyens d'extraire des informations d'une transaction de longue durée - l'une non mentionnée jusqu'à présent est transactions autonomes (qui doit être utilisée avec prudence)

Oui - LogMiner peut le faire. En fait, si vous ne voulez que des transactions validées, vous devez spécifiquement filtrer la sortie! Et voici TABLE_NAME dans V$LOGMINER_CONTENTS, c'est ainsi que vous regarderiez une seule table.

8
Gaius

Il n'y a pas de méthode directe; vous devrez soit analyser les journaux (comme mentionné dans une autre réponse), soit utiliser d'autres méthodes pour voir ce qui se passe dans un processus de longue durée.

Personnellement, je suggère d'utiliser des transactions autonomes pour activer cette fonctionnalité - pas sur la transaction elle-même, mais comme un mécanisme de journalisation vous permettant de savoir ce qui se passe. Par exemple, vous pourriez avoir PROCEDURE LONG_ACTION appeler PROCEDURE WRITE_LOG_ENTRY (défini comme une transaction autonome) qui écrirait un VARCHAR2 dans une autre table. Les transactions autonomes n'interfèrent PAS avec votre transaction actuelle (d'un point de vue LOGIQUE; méfiez-vous des impacts potentiels sur les performances) et vous pouvez donc voir ce qui se passe via vos entrées de journalisation, quel que soit un COMMIT ou un ROLLBACK dans votre transaction actuelle. Cela dit, vous pouvez le faire avec une seule déclaration DML massive; il faudrait utiliser une boucle.

Considérer:

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;

Compte tenu de ce qui précède, vous obtiendrez une entrée de journal pour chaque 500 lignes traitées, quel que soit le succès de l'action longue. Si vous avez besoin d'un duplicata exact des données pour voir comment cela fonctionne, je suggère de créer une table en double et d'appeler une procédure qui dupliquera les données (la procédure étant une transaction autonome). Ensuite, neutralisez les données après coup. (Pas besoin de duplication.)

De plus, si c'est à des fins de débogage, je suggère de supprimer ou de réduire considérablement la nécessité d'une telle journalisation lorsque les choses ont été testées. Et, comme toujours, testez, testez, testez sur votre propre système pour vérifier comment les choses vont fonctionner. (Voir le commentaire de Niall pour un bon exemple de la façon dont la journalisation peut considérablement affecter les performances.)

(Enfin, parce que j'ai négligé de le mentionner auparavant: méfiez-vous des transactions autonomes. Comprenez-les bien avant de les mettre en œuvre, et ne les utilisez pas "simplement parce que". Elles peuvent être utilisées de manière incorrecte d'un million de façons (par exemple, pour ATTEMPT éviter une erreur de mutation dans un déclencheur), il est donc toujours préférable de trouver des alternatives, si possible. Si vous ne le pouvez pas, procédez avec prudence. La journalisation pendant les opérations de longue durée a toujours été un cas où elle est assez sûre problèmes de performances), mais ne vous précipitez pas pour l'appliquer à d'autres utilisations sans en connaître les conséquences.)

5
Kerri Shotts

Non disponible en 10g, mais DBMS_XA peut permettre à une transaction de traverser plusieurs sessions. En utilisant cela, la deuxième session peut voir ce qui se passe dans la transaction

3
Gary

En plus des autres informations ici, d'autres moyens d'envoyer des informations sur une transaction non validée seraient d'envoyer un e-mail ou d'écrire dans un fichier texte.

3
Leigh Riffel