Staraliśmy się wykonać pewne sprawdzenia integralności w naszym stanie bazy danych z powodów diagnostycznych, więc opakowaliśmy nasze zapytania modyfikacji ORM w TransactionScope w połączeniu z drugim zapytaniem, które przeprowadziło diagnostykę - coś takiego:TransactionScope zawijanie wywołań ORM, wyjątek TransactionStateAborted.CreateAbortingClone przy drugim wywołaniu
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, _maxTimeout))
{
ORM.DeleteItem();
ORM.CheckIntegrity();
scope.Complete();
}
jest to ręcznie zwijane ORM, a obie te rozmowy kończy się robi ich trochę w zagnieżdżonych zakresie transakcji na dole. Innymi słowy, kiedy wykopać dół, DeleteItem() ma using (TransactionScope newScope = new TransactionScope (TransactionScopeOptions.Required, _maxTimeout) {...}
i CheckIntegrity() ma również takie same.
W większości przypadków działało poprawnie, ale wystąpił dziwny stan.Jeśli ktoś wkłada jakieś błędne dane wejściowe do kwerendy, wywołanie DeleteItem() może rzucić wyjątek.Ten wyjątek jest całkowicie złapany i obsługiwane w poziom stosu poniżej opakowania.Myślę, że wyjątek jest również wyrzucany przed dostaje się do zagnieżdżenia TransactionScope.
Ale kiedy wchodzimy do tworzenia zagnieżdżonego zakresu w wywołaniu CheckIntegrity(), generuje on komunikat "Transakcja została przerwana" z konstruktora CreateAbortingClone. Wewnętrzny wyjątek jest pusty.
Większość każdej wzmianki o interakcji CreateAbortingClone ma związek z promocją DTC (lub jej awarią), a wewnętrzny wyjątek odzwierciedla to.
Podejrzewam, że przerwanie wyjątku w wywołaniu CheckIntegrity() spowodowane jest faktem, że funkcja DeleteItem() rzuciła wyjątek - mimo że został połknięty.
) Czy to poprawna konkluzja? Czy transakcja jest podatna na wszelkie wyjątki odrzucane, obsługiwane lub nie?
B) Czy istnieje sposób na wykrycie tego przed wykonaniem wywołania CheckIntegrity()? Mam na myśli inne niż ponowne wykonanie ORM, aby wyjątek mógł się przenikać lub dodać inną globalną flagę?
Dzięki Mark
grzebie się trochę bardziej w debugger, uważam, że TransactionScope.expectedCurrent .InternalTransaction.State jest TransactionStateAborted po wywołaniu DeleteItem(), podnosząc moje wnioskowanie. Problem polega na tym, że wszyscy członkowie są prywatni ... – user1664043
Znaleziono dokumentację msdn mówiącą: "Jeśli wyjątek wystąpi w TransactionScope, transakcja jest oznaczona jako niespójna i jest porzucana." ale między wierszami jest dużo niedopowiedzi - jakby nie wydawało się ważne, czy wyjątek obsługuje kilka poziomów połączeń pod zakresem, i zapobiega zagnieżdżaniu się nowych zasięgów. – user1664043
Uwaga w butelce - w końcu znalazłem System.Transactions.Transaction.Current.TransactionInformation.Status i uznałem, że można go użyć do stwierdzenia, czy jakiekolwiek wyjątki (obsługiwane lub nieobsługiwane) zepsuły transakcję pakowania. Jeśli to TransactionStatus. Przyszło mi również do wniosku, że można użyć transakcji zawijania na poziomie zewnętrznym, aby wykryć, kiedy wyjątek został zgłoszony. Przy twoim dalekim zewnętrznym wywołaniu nie możesz oczekiwać kolejnych wywołań db na różne warstwy. Oczywiście lepiej byłoby zaprojektować swój kod, aby nie połknąć istotnych wydarzeń. – user1664043