Announcement

Collapse
No announcement yet.

Keine Transaktion bei verteilter Transaktion mit DTC

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

  • Keine Transaktion bei verteilter Transaktion mit DTC

    Hi,

    ich habe folgende Konstellation:
    • Datenbank ist Oracle 9i
    • Datenbankzugriff per OLE DB und OraOleDb.Oracle
    • Die Oracle-Session wird per JoinTransaction in eine vom DTC kontrollierte Datenbank eingehängt.


    Mein Problem ist nun folgendes: Der Aufruf von JoinTransaction auf der Oracle-Session wird zwar mit S_OK beantwortet, es scheint aber keine Transaktion zu laufen.

    Symptome sind:
    • Jede Änderung gegen die Session ist sofort außerhalb der Transaktion sichtbar (obwohl wir durchgängig ReadComitted verwenden).
    • Nach einem Abort der verteilten Transaktion werden die Änderungen nicht zurückgerollt.


    Die betroffene Anwendung verwendete früher nur lokale Transaktionen - da funktionierte alles einwandfrei.
    Der gleiche Code arbeitet mit dem SQL-Server 2005 wie erwartet.

    Verwendet jemand eine ähnliche Konstellation bei dem es funktioniert?
    Hat jemand eine Ahnung, was da schief laufen könnte?

    Danke
    Jan

  • #2
    Update:

    Ich habe nun den relevanten Programmcode aus der Anwendung in ein Test-Projekt herausgezogen. Und was soll ich sagen... da geht es!

    Bleibt nun noch die Frage: Was kann die Anwendung böses tun, was eine verteilte Transaktion in Oracle verhindert?

    Das Lesen von Datensätzen in der gleichen Sitzung bevor die Transaktion gestartet wird führt nicht zum Problem - das habe ich geprüft.

    Hat noch jemand Ideen?

    Gruß
    Jan

    Comment


    • #3
      # ede Änderung gegen die Session ist sofort außerhalb der Transaktion sichtbar (obwohl wir durchgängig ReadComitted verwenden).
      # Nach einem Abort der verteilten Transaktion werden die Änderungen nicht zurückgerollt.
      Da gibt es nur eine Möglichkeit. Eure Anwendung committet nach jeder Änderung.
      Da Oracle selbst keinen Autocommit kennt (im Gegensatz zum SQL Server etwa) muss es durch die Anwendung passieren (ihr führt keine DDL Anweisungen aus oder? Die würden nämlich die Session auch committen).

      Dim
      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


      • #4
        Hi Dimitri,

        danke für deine Antwort.

        Am Schema ändern wir nichts - also keine DDL-Anweisungen.

        Wenn Oracle selbst keinen Auto-Commit macht (das wusste ich nicht), dann scheint dies der OLE DB Provider zu implementieren. Jedenfalls kann man auch ohne explizit gestartete Transaktion Schreiboperationen durchführen.


        Ich kann noch weitere Beobachtungen melden:
        Wenn ich im Test-Projekt eine verteilte Transaktion gestartet habe, führt ein anschließender StartTransaction Aufruf auf der gleichen Session fehl - so wie man das erwarten würde.
        Wenn ich das gleiche in der eigentlichen Anwendung mache, bekomme ich keine Fehlermeldung, aber das gleiche Fehlverhalten -> es wird alles sofort committed.

        Als weiteren Test habe ich einmal direkt nach dem JoinTransaction eine Schreiboperation durchgeührt. Da zeigt sich bereits das gleiche Verhalten -> Der Fehler liegt demnach nicht nach dem Starten der Transaktion sondern er muss irgend wo davor liegen.

        Bei Gelegenheit werde ich einmal versuchen, in der eigentlichen Anwendung alle Operationen vor dem JoinTransaction Schritt für Schritt auszulassen bis ich den Bösewicht gefunden habe. Das kann allerdings etwas dauern, weil dieses Projekt bei uns mittlerweile eine niedrigere Prio bekommen hat.


        Danke an alle, die sich Gedanken gemacht haben.

        Falls noch jemandem etwas einfällt...
        Jan

        Comment


        • #5
          Hi,

          wenn Du in der Testumgebung entsprechende Rechte hast oder ein DBA dir hilft, könntest über einen Logon Trigger die Sesssion tracen und dann im Tracefile sehen, wann der commit ausgeführt wird. Dort steht zwar nicht wer es gemacht hat, aber evtl. helfen die die SQLs die direkt davor kommen bei der fehersuche.

          Vergiss aber nicht den Trigger danach wieder zu droppen!
          Code:
          CREATE OR REPLACE TRIGGER logon_trace
          AFTER LOGON ON DATABASE
          BEGIN
          IF USER='Dein_Schema_User' THEN
           EXECUTE IMMEDIATE 'ALTER SESSION SET EVENTS ''10046 trace name context forever, level 8''';
          END IF;
          END;
          /
          Das Tracefile wird in den Userdump Ordner geschrieben. Das findest so raus:
          Code:
          select value from v$parameter where name='user_dump_dest';
          Der Trigger muss als sys oder system angelegt werden.

          Dim
          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


          • #6
            Oh Mann - ich glaub's nicht!!!

            Hi, ich habe das Problem gefunden:
            Um zu verhindern, dass sich Oracle selbständig und damit versehentlich an einer MTS-Transaktion beteiligen kann, wurde in den Connection-String (das ist jetzt schon 5 Jahre her) folgendes eingebaut:

            Code:
            DistribTX=0
            Damit konnte natürlich keine verteilte Transaktion mehr funktionieren. Ich hab's erst beim schrittweisen Debuggen gesehen.

            @Dimitri
            Ich danke dir vielmals für deine Tipps.

            Gruß
            Jan

            Comment


            • #7
              Da Oracle selbst keinen Autocommit kennt (im Gegensatz zum SQL Server etwa)
              Stimmt so nicht ganz.
              Oracle kennt durchaus Autocommit:

              Syntax: SET AUTO[COMMIT]{ON|OFF|IMM[EDIATE]|n}

              Im Gegensatz zum SQL Server ist autocommit standardmäßig OFF.

              kuemmelchen

              Comment


              • #8
                Stimmt so nicht ganz.
                Oracle kennt durchaus Autocommit:
                Das ist sql*plus also eine Clientanwendung die von sich aus eben einen COMMIT absetzt.
                Das hat nichts mit der DB an sich zu tun. Oracle kennt definitiv kein Autocommit.

                Dim
                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

                Working...
                X