Wir haben versucht, den Datenbankstatus aus diagnostischen Gründen zu überprüfen. Daher haben wir unsere Modifikations-ORM-Abfragen in einem TransactionScope zusammen mit einer zweiten Abfrage mit Diagnosefunktionen verpackt. so etwas wie dieses: tun ihr Bit in einem verschachtelten TransaktionsbereichTransactionScope Wrapping von ORM-Aufrufen, TransactionStateAborted.CreateAbortingClone-Ausnahme beim zweiten Aufruf
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, _maxTimeout))
{
ORM.DeleteItem();
ORM.CheckIntegrity();
scope.Complete();
}
Es ist eine handgerollte ORM, und beide diese Anrufe am Ende nach unten am Boden. Mit anderen Worten, wenn Sie graben, DeleteItem() hat mit (Transaction newScope = new Transaction (TransactionScopeOptions.Required, _maxTimeout) {...}
und CheckIntegrity() auch das gleiche hat.
In den meisten Fällen hat es funktioniert, aber ich bin über eine seltsame Bedingung gelaufen.Wenn jemand einige schlechte Eingaben in die Abfrage eingibt, kann der DeleteItem() Aufruf eine Ausnahme auslösen.Diese Ausnahme wird komplett gefangen und behandelt bei a Stacklevel unter dem Wrapper Ich glaube, dass auch Exception vor geworfen wird, um das TransactionScope zu verschachteln
Wenn wir jedoch beim CheckItegrity() - Aufruf zur Erstellung des verschachtelten Bereichs gelangen, wird vom CreateAbortingClone-Konstruktor ein Fehler "Transaktion wurde abgebrochen" ausgegeben. Die innere Ausnahme ist null.
Die meisten anderen Erwähnung der CreateAbortingClone-Interaktion hat mit DTC-Promotion (oder Fehler davon) zu tun und die innere Ausnahme spiegelt das wider.
Ich folge daraus, dass die Abbruch-Ausnahme beim Aufruf von CheckIntegrity() darauf zurückzuführen ist, dass DeleteItem() eine Ausnahme ausgelöst hat - obwohl sie verschluckt wurde.
A) ist das eine korrekte Schlussfolgerung? Ist ein TransactionScope anfällig für Ausnahmen, die ausgelöst oder bearbeitet werden?
B) Gibt es eine Möglichkeit, dies vor dem CheckIntegrity() - Aufruf zu erkennen? Ich meine anderes als unsere ORM wieder zu tun, um die Ausnahme percole oder eine andere globale Flagge hinzuzufügen?
Dank Mark
Stochern ein bisschen mehr im Debugger, finde ich, dass TransactionScope.expectedCurrent .InternalTransaction.State ist TransactionStateAborted nach dem DeleteItem() - Aufruf, der meine Inferenz unterstützt. Problem ist, dass alle Mitglieder privat sind ... – user1664043
msdn docs gefunden "Wenn eine Ausnahme innerhalb des TransactionScope auftritt, wird die Transaktion als inkonsistent markiert und abgebrochen." Zwischen den Zeilen bleibt jedoch eine Menge ungesagt. So scheint es keinen Unterschied zu machen, ob die Ausnahme einige Aufrufebenen unterhalb des Bereichs behandelt, und verhindert, dass neue Bereiche anschließend verschachtelt werden. – user1664043
Hinweis in einer Flasche Zeit - schließlich fand ich System.Transactions.Transaction.Current.TransactionInformation.Status und dachte, es kann verwendet werden, um festzustellen, ob irgendwelche Ausnahmen (behandelt oder nicht behandelt) Ihre Wrapping-Transaktion verdorben haben. Wenn es sich um TransactionStatus.Aborted handelt, bist du abgespritzt. Es ist mir auch aufgefallen, dass Sie eine Wrapping-Transaktion auf einer äußeren Ebene verwenden können, um festzustellen, wann eine Ausnahme ausgelöst wurde. Bei Ihrem äußersten äußeren Aufruf müssen Sie keine aufeinanderfolgenden db-Aufrufe in verschiedenen Layern erwarten. Natürlich wäre es besser, Ihren Code so zu gestalten, dass er wichtige Ereignisse nicht verschluckt. – user1664043