none
TRY ... CATCH und Transaktionen RRS feed

  • Frage

  • Hallo,

    ich habe gerade ein Problem mit dem Verhalten eines TRY ... CATCH Blocks das beim Auftreten einer Exception die laufende Transaktion in einen nicht mehr commitbaren Zustand fällt. Ich würde gern wissen ob man dieses Verhalten ändern kann (dahingehend das sich der Transaktionszustand nicht durch eine Exception ändert) oder ob es eine Ansatz gibt das Problem zumindest zu umgehen.

    Ok. Was habe ich im Moment. Ich habe eine kleine Struktur aus 2 Tabellen die ich im Bulk updaten will(über die SqlBulkCopy Klasse aus dem .Net Framework). Dazu habe ich eine Stellvertreter-Tabelle mit einem Trigger erstellt auf die der Bulk update läuft. Der Trigger (Instead of Insert) geht dann hin und verteilt die Daten auf meine beiden Tabellen. Wobei eine der beiden Tabellen bereits entsprechende Daten enthalten könnte. Dann bräuchte ich für die 2.te Tabelle nur den PK des Datensatzes. Der entscheidende Teil des aktuellen Triggers als Pseudocode

    FETCH NEXT FROM inserted_cursor INTO @Id, @Feld1, @Feld2, ...
    WHILE @@FETCH_STATUS = 0
    BEGIN
      IF (@Id IS NULL)
      BEGIN            
         BEGIN TRY
            INSERT INTO Tabelle1(Feld1, Feld1) VALUES(@Feld1, @Feld1)   
            SELECT @Id = @@IDENTITY
         END TRY      
         BEGIN CATCH            
            SELECT @Id = Id FROM Tabelle1 WHERE Feld1 = @Feld1 AND Feld2 = @Feld2
         END CATCH                        
      END           
      INSERT INTO Tabelle2(Id, ...) VALUES (@Id, .....)
      FETCH NEXT FROM inserted_cursor INTO @Id, @Feld1, @Feld2, ...
    END

    Der inserted_cursor wird so zusammengebaut das dieser schon prüft ob in Tabelle1 ein entsprechender Satz gefunden werden kann. Wenn der fehlt wird versucht das nachzuholen. Aus Konkurrenzproblemen kann sich das aber mittlerweile geändert haben, unwahrscheinlich aber möglich. In dem Fall bräuchte ich die ID des dann doch vorhandenen Satzes und würde meine Operationen einfach fortsetzen. Dieser Trigger ist performancekritisch insofern würde ich gern auf großes Locking auf Tabelle1 verzichten.

    Deshalb der Ansatz TRY ... CATCH zu verwenden. Seltenes Ereignis und eigentliche Operation(INSERT) im Normalfall sehr schnell. Leider wird halt wenn es zur Key Violation auf Tabelle1 kommt auch die Transaktion beendet.

    Was für Möglichkeiten habe ich?

    Ralf


    • Bearbeitet Ralf Jansen Freitag, 10. Februar 2012 10:47
    Freitag, 10. Februar 2012 10:44

Antworten

Alle Antworten