2016-05-20 6 views
0

Ich habe ein Problem mit X ++. Lets sagen, dass ich eine Transaktion haben, wie dieseX ++ ttsbegin und ttsAbort

Custtable custTable; 
ARandomTable mytable; 
; 
ttsBegin; 
    select forUpdate custTable where custTable.AccountNum == '4000'; 
    custTable.NameAlias = custTable.Name; 
    custTable.update(); 
    ttsBegin; 
     select forUpdate mytable where mytable.myField == 'abc'; 
     mytable.myField = 'xyz'; 
     mytable.update(); 
     //ups something wrong happened... please abort the last 
    ttsAbort; 
ttsCommit; 

in Pseudo-Code sieht Warum die ttsAbort die gesamte Transaktion abbrechen und nicht derjenige, der zuletzt begonnen? Gibt es eine Möglichkeit, es zu vermeiden?

+0

Einige gute Antworten unten.Wenn möglich, sollte die '// ups etwas falsch passiert 'in eine' checkX' Methode konvertiert werden, die vor dem ersten oder sogar zweiten 'ttsBegin;' –

Antwort

6

Warum bricht das ttsAbort die gesamte Transaktion ab und nicht die, die zuletzt gestartet wurde?

Dieses Verhalten sorgt für die transaction integrity der Transaktion, die mit dem ersten ttsBegin gestartet wurde. Im Grunde ist diese erste ttsBegin wie: "Starten Sie eine neue Transaktion und in Bezug auf die Datenbank betrachten Sie alles in dieser Transaktion als eine einzige (atomare) Aktion. Die Transaktion endet, wenn Sie eine ttsCommit (auf der die Aktion gegen die ausgeführt wird Datenbank) oder ein ttsAbort (auf nichts wird in der Datenbank getan werden). "

Wenn nach den ersten ttsBegin anderen ttsBegin angetroffen wird, ist dies wie wenn man sagt: „Für jeden ttsBegin Sie nach dem ersten Begegnung, ignoriert eine ttsCommit

Da eine Transaktion als einzelne atomare Aktion betrachtet wird, können Sie einen Teil dieser Aktion nicht einfach abbrechen.

Gibt es eine Möglichkeit, dies zu vermeiden?

In Ihrem Fall, nein. Es gibt jedoch eine Möglichkeit, sicherzustellen, dass ein Teil einer Transaktion in die Datenbank übernommen wird, selbst wenn die gesamte Transaktion abgebrochen wird. Dies geschieht mit einem separaten UserConnection für die innere Transaktion. Weitere Informationen finden Sie unter How to create a separate transaction using UserConnection to ensure your transaction is not rolled back at a higher level .

+0

aufgerufen wird. Die Antwort sieht gut aus und die von Ihnen angebotene Verbindung sieht vielversprechend aus. Ich werde es versuchen und Sie wissen lassen, ob es funktioniert hat – Bongo

4

Wie SQL ROLLBACK TRANSACTIONttsAbort rollt alle Anweisungen auf die äußerste Transaktion zurück.

Rolls zu Beginn der Transaktion eine explizite oder implizite Transaktion zurück

Im AX/x ++ die gleiche Regel gilt für Ausnahmen.

Ausnahmen innerhalb von Transaktionen

Wenn eine Ausnahme innerhalb einer Transaktion ausgelöst wird, wird die Transaktion automatisch abgebrochen (a ttsAbort Operation auftritt). Dies gilt sowohl für Ausnahmen, die manuell ausgelöst werden, als auch für Ausnahmen, die vom System ausgelöst werden.

Wenn eine Ausnahme in einem Transaktionsblock ttsBegin - ttsCommit ausgelöst wird, kann keine catch-Anweisung in diesem Transaktionsblock die Ausnahme verarbeiten. Stattdessen sind die innersten catch-Anweisungen, die sich außerhalb des Transaktionsblocks befinden, die ersten zu testenden catch-Anweisungen.

Und ttsAbort ist obsolete. Verwenden Sie stattdessen throw.

Verwandte Themen