Announcement

Collapse
No announcement yet.

Nested Transactions

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

  • Nested Transactions

    Hallo,

    ich möchte mehrere DS aus verschiedenen Tabellen von einem Client auf einem Server synchronisieren und umgekehrt. Die Routinen zur Synchronisation sind soweit fertig und funktionieren auch. <br>
    Mein Problem ist jetzt aber die Transaktionssteuerung. Sobald ein Fehler auftritt, will ich alle (auch erfolgreich) durchgeführten Änderungen (Insert, Update, Delete) rückgängig machen. <br>
    Zur Zeit verwende ich dafuer die explizite Transaktionssteuerung durch BeginTrans und CommitTrans bzw. RollbackTrans. Natuerlich weis ich das dies nicht der optimale Weg ist. Leider habe ich es aber nicht geschafft den MTS soweit zu konfigurieren das er auch die erfolgreich durchgefuehrten Transaktionen rückgängig macht. <br>
    <br>
    Zum Testen habe ich versucht das Beispiel Projekt aus dem Kapitel 9.6 "Nested Transactions mit COM+" aus dem Buch "Ado und Delphi" anzupassen, da dies auch meine Rechnerkonfiguration (Sql-Server, three-tier, com+) wiederspiegelt. In dem Beispiel währe es dann so, das nach einem erfolgreichem Einfuegen eines Datensatzes und einem provoziertem SetAbort kein DS in der SQL DB existieren duerfte. <br>
    <br>
    Wie schaff ich das? Vielen Dank für eure Hife. <br>
    Daniel Auth

  • #2
    Hallo,

    &gt;Wie schaff ich das?

    der Entwickler muss an dieser Stelle nicht eingreifen, dass macht COM+ automatisch. Wenn bei einem SetAbort-Aufruf der Datensatz nicht implizit über ein ROLLBACK widerrufen wird, ist es das Beste, den <i>Profiler</i> des MS SQL Server auf die Lauer zu legen, um die Ursache für dieses Problem einzukreisen (siehe Abbildung 9.15 auf Seite 448).

    Parallel dazu kann man im MMC-Snapin für die <i>Komponentendienste</i> im Zweig <i>Districuted Transaction Coordinator</i> die Seite <b>Transaktionsstatistik</b> aufrufen. Dort wird jeder SetComplete-/SetAbort-Aufruf mitgezählt. Erhöht sich dort die Anzeige in der Spalte <i>Abgebrochen</i>, wenn das eigene COM+ Objekt die Methode <i>SetAbort</i> aufruft

    Comment


    • #3
      Hallo,

      ein Rollback über SetAbort funktioniert. Allerdings nur fuer die zuletzt benutzte Transaktion. Der DS der ein SetAbort provoziert wird also durch ein Rollback zurueckgenommen. Ich möchte aber, dass auch der vorherige, mit SetComplete abgeschlosssene, DS zurueckgenommen wird. Die Insert Anweisung (bzw. die Stored Procedure) fuer diesen DS läuft aber in einer eigenen Transaktion die nach dem SetComplete ja abgeschlossen ist. <br>
      <br>
      Ich denke, dass ich fuer die Lösung noch eine "uebergeordnete" Transaktion benötige. In etwa sollen die Transaktionen wie folgt ablaufen: <br>
      <br>
      Start Transaktion 1 <br>
      Start Transaktion 1 1 <br>
      INSERT DS 1 <br>
      Ende Transaktion 1 1 durch Commit <br>
      <br>
      Start Transaktion 1 2 <br>
      INSERT DS 2 <br>
      Ende Transaktion 1 2 durch Rollback <br>
      Ende Transaktion 1 durch Rollback <br>
      <br>
      d.h. es darf auch nicht mehr der zuerst eingefuegte DS 1 in der DB stehen (Atomicity Eigenschaft!) <br>
      <br>
      Wie schaffe ich es das der MTS die "übergeordnete" Transaktion 1 erstellt?<br>
      Daniel Auth <br>
      <br>
      PS: der Profiler des MS Sql Servers zeigt immer nur einen Nested Level von 1 an

      Comment


      • #4
        Hallo,

        &gt;Wie schaffe ich es das der MTS die "übergeordnete" Transaktion 1 erstellt?

        für diesen Einsatzfall unterscheidet der MTS bzw. COM+ zwischen den Transaktions-Attributen <i>Neu erforderlich</i> und <i>Erforderlich</i> (siehe Eigenschaftsdialog | Registerseite Transaktionen). Der Entwickler kann sich zwischen 2 Alternativen entscheiden:

        1. Alternative: MTS/COM+ Objekt behält zwischen den beiden Aufrufen für das Einfügen von DS1 und DS2 den Zustand: <br>
        a) Client ruft die Interface-Methode auf, um den DS1 einzufügen<br>
        b) MTS/COM+ Objekt ruft <b>EnableCommit</b> auf, um die Transaktion offen zu halten <br>
        c) Client ruft die Interface-Methode auf, um den DS2 im Kontext der <b>gleichen</b> Transaktion einzufügen <br>
        d) MTS/COM+ Objekt ruft <B>SetAbort</b> auf, um beide Datensätze (DS1+DS2) über einen Rollback zurückzunehmen

        2. Alternative: Zwei MTS/COM+-Objekte mit unterschiedlicher Konfiguration: <br>
        a) Das erste MTS/COM+-Objekt mit der Transaktions-Einstellung <i>Neu erforderlich</i> legt den DS 1 im Kontext einer <b>neuen</b> Transaktion an <br>
        b) Das zweite MTS/COM+-Objekt mit der Transaktions-Einstellung <i>Erforderlich</i> legt DS2 an, wobei es automatisch beim Aufruf aus dem 1. Objekt heraus im bereits <b>bestehenden</b> Transaktionskontext ausgeführt wird <br>
        c) Das erste MTS/COM+-Objekt ruft SetAbort auf - beide Datensätze werden über ROLLBACK zurückgenommen.

        &gt;..einen Nested Level von 1 an.

        Der Abschnitt 9.6 in meinem Buch betrachtet den Sonderfall, dass eine deklarative COM+ Transaktion die innerhalb einer Stored Procedure aufgerufene T-SQL-Transaktion "überstimmt". Generell gilt, dass die COM+ Transaktion das Gesamtverhalten bestimmt. Daher ist es normal, wenn der Profiler immer nur den maximalen Wert von 1 anzeigt.

        P.S: In T-SQL würde eine verschachtelte Transaktion so aussehen:
        <pre>

        BEGIN TRAN TestMainTransaction
        ...
        SAVE TRAN TestBookmark1
        ...
        ROLLBACK TRAN TestBookmark1
        ...
        COMMIT TRAN

        </pre>

        Comment

        Working...
        X