2012-12-19 16 views
12

Czy istnieje powód, aby nie używać dynamic-insert/dynamic-update dla NHibernate? Jedynym powodem, dla którego pytam, jest to, że wydaje mi się, że chciałbym go włączyć jako domyślny, a nie jako coś, co musiałbym skonfigurować.Aktualizacja dynamiczna NHibernate Wady?

Czy są jakieś pomysły, o których należy pamiętać podczas korzystania z tych właściwości dynamicznych?

Odpowiedz

23

Dla niektórych podmiotów można utworzyć nieprawidłowy stan za pomocą aktualizacji dynamicznych. Załóżmy, że masz Class o wartości Boolean Właściwość A i logicznie zależną od siebie. Jeśli właściwość A to True, właściwość B może być tylko liczbą ujemną, natomiast jeśli właściwość A to False, wówczas właściwość B może być tylko liczbą dodatnią.

Załóżmy, że dwóch użytkowników jednocześnie wchodzi w interakcję z wystąpieniem tej klasy w określonym przedziale czasu. Aby rozpocząć, użytkownicy Alicja i Bob zarówno urzeczywistnić tę klasę z bazy danych, z początkowych wartości A = True i B = -50

Database Alice  Bob 
A: True A: True  A: True 
B: -50  B: -50  B: -50 
VALID  VALID  VALID 

Alice użytkownik zmieni A do False i B do 125, i zobowiązuje się je do bazy danych. Teraz mamy taką sytuację:

Database Alice  Bob 
A: False A: False A: True 
B: 125  B: 125  B: -50 
VALID  VALID  VALID 

Użytkownik Bob nie zmienia A, ale zmienia B do -75, a następnie zobowiązuje go do bazy danych. Jeśli aktualizacje dynamiczne są włączone, to NHibernate widzi, że Bob zmienił tylko B na -75 i wydaje dynamiczną aktualizację, która edytuje tylko wartość B. Jeśli sprawdzanie poprawności SQL na serwerze uniemożliwiłoby uzyskanie wartości ujemnej B, o ile nie podano wartości A, wystąpiłby błąd SQL, ale załóżmy, że nie powielono całej logiki biznesowej na tabelach SQL. Oto wynikowe dane:

Database Alice  Bob 
A: False A: False A: True 
B: -75  B: 125  B: -75 
INVALID VALID  VALID 

Zarówno Alicja jak i Bob mają prawidłowe stany, ale Baza danych jest teraz w nieprawidłowym stanie! Użytkownik Charlie przychodzi i próbuje urzeczywistnić ten rekord:

Database Alice  Bob  Charlie 
A: False A: False A: True A: False 
B: -75  B: 125  B: -75 B: -75 
INVALID VALID  VALID  INVALID 

Charlie prawdopodobnie pojawia się błąd walidacji z aplikacji podczas NHibernate próbował ustawić właściwość B nowej instancji klasy.

Tak więc, jeśli masz właściwości zależne logicznie, musisz mieć pewną strategię, aby uniknąć tej sytuacji. Jedną z możliwości jest po prostu włączyć select-before-update dla tego obiektu. Może to spowodować dodatkowe wywołania bazy danych i nieco wolniejszą wydajność. Innym sposobem jest wykorzystanie wersji w NHibernate, co oznaczałoby, że gdy Bob spróbuje zapisać swój rekord, zapytanie wstawiania NHibernate nie wyzwoli żadnych zapisów i wyrzuci wyjątek danych stałych (który może być z wdziękiem obsłużony). Możesz również skodyfikować wymagania logiczne swojej klasy w bazie danych, jednak musisz zachować ostrożność, aby upewnić się, że baza danych i program mają te same skodyfikowane wymagania co czas, a będziesz mieć wiele miejsc do wprowadzaj zmiany, gdy zmieniają się wymagania, co nie zawsze jest opłacalne.

Krótko mówiąc, w wielu okolicznościach programista musi ostrożnie obsługiwać szczegóły aktualizacji dynamicznych, dlatego nie jest domyślnie włączony.Po włączeniu należy rozważyć, czy częściowe aktualizacje jednostki mogą spowodować problemy, a jeśli tak, to użyj jednej ze strategii łagodzenia zalecanych w celu ochrony przed tym problemem.

+0

Bardzo przydatne. Nie wiedziałem nawet o wyborze przed aktualizacją. Z pewnością o tym pamiętam. – Sam

+2

W tym przykładzie aplikacja zezwoliła użytkownikowi na zatwierdzenie zmian, gdy jednostka była w niepoprawnym stanie. Klasa powinna hermetyzować dostęp do tych właściwości, aby reguła biznesowa została wymuszona i/lub jednostka powinna zostać zatwierdzona przed zatwierdzeniem transakcji. Nie widzę, aby miało to coś wspólnego z aktualizacją dynamiczną. –

+0

Brakuje ci lekcji: kopia istoty Boba nie była w nieprawidłowym stanie. Jednostka stała się nieważna tylko wtedy, gdy aktualizacja dynamiczna zmieniła wartość właściwości B bez informacji, że utrwalona wartość właściwości A spowodowałaby niepoprawną wartość. –

5

Dynamiczne wstawianie i aktualizowanie ma niewielki koszt wydajności, ponieważ NHibernate musi za każdym razem konstruować SQL zamiast go buforować. Nie wiem, czy po stronie bazy danych jest koszt. Dynamiczne wstawianie i aktualizacja są bardzo przydatne podczas rozwiązywania problemów i profilowania. Gdybym był w stanie zmierzyć znaczący hit wydajności, włączałbym go w fazie projektowania i wyłączania w produkcji.

Możesz napotkać problemy ze słuchaczami i przechwytującymi, zobacz this question.

Mam go włączony w moich aplikacjach NHibernate bez żadnych problemów. Moja odpowiedź brzmi: nie, nie ma dobrego powodu, aby jej nie używać.

+0

Interesujące komentarze na temat buforowania. Kiedy patrzę na SQL wygenerowany przy użyciu log4net, nadal wydaje się, że używa sparametryzowanych zapytań. Czy te miejsca nie zostaną zbuforowane gdzieś po linii? Co więcej, nie zostawiając dynamicznych zapytań wyłączonych, również osiągi zostały osiągnięte przez aktualizację pól, które się nie zmieniły? A może ten koszt jest znikomy? Dzięki za opinie. – Sam

+2

NHibernate może buforować statyczny format zapytania, tak aby tworzenie zapytania wypełniało puste pola. W przypadku zapytań dynamicznych kwerenda musi być skonstruowana za każdym razem. Wynik działania aktualizacji wszystkich pól, jeśli taki istnieje, zależy od bazy danych. Jest wiele czynników, ale moja opinia i doświadczenie sprawiają, że zalecam stosowanie dynamicznej wstawki i aktualizacji. –