Bez kategorii

Entity Framework – NIGDY NIE ROBIĆ ZAPISU W PĘTLI

Przejąłem po koledze aplikację. Ach Ci kochani koledzy. Serwis wywołujący komponenty w różnych wątkach co same w sobie nie jest złe jeżeli ma się nad tymi wątkami kontrolę, ale jak nie trzeba sobie życia utrudniać to można wywoływać w jednym serwisie wszystkie komponenty po kolei.
Implementacja Unit of Work była, a i owszem, nadawała się do rubry WTF. Była tylko nie za bardzo rozumiałem po co, bo Save Savem poganiał, a to raczej w poprzek koncepcji UoW stoi.
Proces w3wp odpowiedzialny za aplikację webową potrafił spuchnąć do 4GB, a aplikacja ma 25 użytkowników w tym 15 nieaktywnych (nie mogą się nawet zalogować), a reszta korzysta z aplikacji od wielkiego dzwona.
Zastosowano kontener, ale zależności były przekazywane jako argumenty konstruktorów i metod …

Po 12 godzinach mogę powiedzieć … Dałem radę.

Wywaliłem UoW, bo moim zdaniem jak nie jest potrzebny, a tym bardziej jak jest źle zaimplementowany to nie trzeba go używać. Wymieniłem kontener na Autofaca, bo go znam i lubię i utknąłem na serii błędów w stylu:

ExecuteReader requires an open and available Connection. The connection’s current state is open
The underlying provider failed on open
Połączenie nie zostało zamknięte. Obecny stan połączenia: otwarte
New transaction is not allowed because there are other threads running in the session
An error occurred while starting a transaction on the provider connection. See the inner exception for details.

Ale udało się w końcu zapanowac nad bałaganem, a najważniejsze to:

  1. Gdy tworzymy nowe obiekty w pętli to SaveChanges zrobić poza nią.
  2. Gdy tworzymy kilka obiektów różnych klas w pętli to nie podstawiamy identyfikatorów, tylko całe obiekty i oczywiście SaveChanges() poza pętlą.
  3. To samo dotyczy aktualizacji.

I wtedy można spać spokojnie.

Leave a Reply

Your email address will not be published. Required fields are marked *