Announcement

Collapse
No announcement yet.

Cachrefresh bei Nutzung von DBLinks

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cachrefresh bei Nutzung von DBLinks

    Hallo,
    folgendes Szenario:

    Ein übergeordnetes System bedient mehrere untergeordnete Systeme mit Daten. Die Verbindungen zwischen den über- und untergeordneten Systemen sind durch DBLinks realisiert.

    Das Auslesen vom untergeordneten System funktioniert so:
    select * into var from tabelle1@dblink1;
    Danach erfolgt ein insert ins unterg. System mit Parametern.


    Nun kann es vorkommen, dass Spalten in tabelle1 hinzukommen. Ich musste feststellen, dass es in diesem Fall zu einem Laufzeitfehler auf dem untergeordneten System kommt, da die Session wohl noch die alte Tabellendefinition im Cache hat.

    Gibt es eine Möglichkeit einen Art Cacherefresh auf den untergeordneten Systemen zu erzwingen ohne das die Session neu gestartet werden muss? Einen Zeitpunkt zu finden in dem alle untergeordneten Systeme sich nicht in Produktion befinden und ich die Prozesse neu starten kann ist recht schwierig.

    Danke schon mal für die Hilfe!
    Mephi
    Zuletzt editiert von Mephisto84; 22.01.2013, 15:26.

  • #2
    Du kannst den DB Link schliessen:

    Code:
    ALTER SESSION CLOSE DATABASE LINK dblink1;
    Verwendet ihr "Result Cache"? Wenn ja kannst du ihn im Statement mit dem Hint /*+ NO_RESULT_CACHE */ abschalten.

    Gruss

    Comment


    • #3
      Hallo Wernfried,
      danke für deine Antwort!

      Du meinst, wenn der DBLink kurzzeitig geschlossen ist, wird der gesamte Cache, der den DBLink betrifft gelöscht?
      Reicht da das kurzzeitige Schließen oder muss der geschlossene DBLink einmalig verwendet werden damit der Cache gelöscht wird?


      Die untergeordneten Systeme haben die Einstellung: result_cache_mode = manual

      Comment


      • #4
        Den DB Link zu schliessen war nur eine Vermutung von mir - Ich weiss nicht genau wo und was da gelöscht wird.

        Den Result Cache musst du auf der übergeordneten DB abschalten, also dort wo das Select gemacht wird. Das ist ja gerade der Sinn des Result Cache. Wenn die Daten aus dem Momory der Remote DB geholt werden müssen gewinnst du u.U. nicht so viel.

        Gruss

        Comment


        • #5
          Wieso denn die übergeordnete? Es geht doch um die Aktualisierung der Tabelleninformationen auf der untergeordneten.

          Noch mal anders ausgedrückt:

          DB A: Tab1 wird um Spalte erweitert
          DB B macht select auf Tab1 der Datenbank A, hat aber in ihren Sessioninformationen noch die Infos vor der Tabellenerweiterung. Zur Laufzeit gibts nen Fehler, dass x Spalten erwartet werden aber x+1 Spalten zurück kommen.

          Also es müsste doch um den Cache der DB B (der untergeordneten gehen), DB A hat doch damit nix zu tun. oder?

          Comment


          • #6
            Irgendwie bin ich mit über- und untergeordneter DB durcheinander gekommen.

            Wie sieht denn dein Code und die Fehlermeldung genau aus, bzw. wann kommt der Fehler? Ich kann mir kaum vorstellen, dass ein einfaches "Select * from ..." einen Fehler auslöst.

            Gruss

            Comment


            • #7
              Hallo,
              also ich bekam den Fehler:
              ORA-06508: PL/SQL: could not find program unit being called

              Ich versuche schon die ganze Zeit den Fehler auf der Testdatenbank zu reproduzieren. Bisher ohne Erfolg.
              Den einzigen Fehler den ich bekommen habe war: ORA-04062: Timestamp von package xy wurde geändert.
              Der Aufbau war wie folgt:
              DB B greift über DBLink auf Package P auf DB A zu. Dort wird ein select auf eine Tabelle von B durchgeführt. (Das ist sehr stark vereinfacht aus das Szenario mit meinem Problem).

              Wenn ich nun das Package P in DB A neu kompiliere erfolgt der o.g. Fehler.
              Beim 2. Mal ausführen funktioniert es (da er sich wohl selbst Aktualisiert hat)




              Meine Vermutung ist jetzt, dass genau dieses Aktualisieren im Livesystem nicht funktioniert, da die Prozesse das Rekompilieren unnöglich machen.

              Comment


              • #8
                Die genannten Fehler haben nichts mit einem DB Link zu tun. Du versuchst eine PL/SQL Routine aufzurufen, die nicht existiert bzw. in der Zwischenzeit wurde das Package in einer anderen Session geändert.
                Fang den Fehler in einem EXCEPTION Block ab und reagiere entsprechend darauf.
                Zitat Tom Kyte:
                I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                Comment


                • #9
                  Originally posted by dimitri View Post
                  ... bzw. in der Zwischenzeit wurde das Package in einer anderen Session geändert.
                  Fang den Fehler in einem EXCEPTION Block ab und reagiere entsprechend darauf.
                  Wie soll ich denn darauf reagieren?
                  Also darum gehts ja, wie kann ich die Session dazu zwingen sich zu aktualisieren. Normalerweise würde sie dies ja automatisch tun, aber (so meine Vermutung) sie tut dies nicht, da die Prozesse das Recompilen/Aktualisieren des Packages verhindern.

                  Comment


                  • #10
                    Du kannst DBMS_SESSION.RESET_PACKAGE verwenden oder aber fehlgeschlagenen Aufruf einfach wiederholen. RESET_PACKAGE setzt allerdings alle mit der Session assoziierten Packagevariablen etc. wieder zurück, also vorsichtig verwenden. Allerdings passiert das auch, wenn die Packages neu kompiliert werden, insofern...

                    Deine Vermutung bezüglich des automatische Refresh ist nicht richtig. Oracle erkennt anhand eines Zeitstempels, dass sich am Package etwas geändert hat. Das ist nicht zeitabhängig, sondern wird geprüft, wenn das Package aufgerufen wird.
                    Wer im laufenden Betrieb Packages aktualisiert, muss auch mit diesen Exceptions zurechtkommen und abfangen, da führt leider kein weg dran vorbei. Du musst auch damit rechnen, dass ggf. verwendete Variablen wieder leer sind.
                    Zitat Tom Kyte:
                    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                    Comment


                    • #11
                      Originally posted by dimitri View Post
                      Die genannten Fehler haben nichts mit einem DB Link zu tun. Du versuchst eine PL/SQL Routine aufzurufen, die nicht existiert bzw. in der Zwischenzeit wurde das Package in einer anderen Session geändert.
                      Fang den Fehler in einem EXCEPTION Block ab und reagiere entsprechend darauf.
                      In diesem Fall ist es wohl eher so, dass ein Objekt (d.h. jene Tabelle) geändert wurde, z.B. eine Spalte hinzugefügt und diese Package eine Abhänigeit auf diese Tabelle hat, z.B. weil ein
                      Code:
                       var tabelle1%ROWTYPE;
                      verwendet wird.

                      In diesem Fall muss du entweder das Package neu compilieren oder DBMS_SESSION.RESET_PACKAGE ausführen.
                      Eine andere Möglichkeit könnte sein sich neu an der DB anzumelden. Wenn ein PL/SQL Package das erste Mal aufgerufen werden soll und es ungültig ist wird es automatisch noch einmal kompiliert.

                      Gruss

                      Comment


                      • #12
                        Danke für eure Hilfe! Habt mir weiter geholfen!

                        Comment

                        Working...
                        X