Dlaczego potrzebuję Transakcji w hibernacji do operacji tylko do odczytu?
Czy następująca transakcja powoduje zablokowanie bazy danych?
Przykładowy kod do pobrania z DB:
Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here
tx.commit() // why tx.commit? I don't want to write anything
Czy mogę użyć session.close()
zamiast tx.commit()
?
java
database
hibernate
transactions
database-connection
user93796
źródło
źródło
Odpowiedzi:
W rzeczywistości możesz mieć powody, aby oznaczać transakcje jako tylko do odczytu.
autocommit=true
jeśli inna opcja nie zostanie wyraźnie ustawiona.@Transactional(readonly=true)
, Spring ustawi transakcję JDBC w tryb tylko do odczytu, więc zdecydujesz, czy to faktycznie można zapisywać do bazy danych w ramach tej transakcji. Jeśli twoja architektura jest uciążliwa i niektórzy członkowie zespołu mogą zdecydować się na umieszczenie zapytania modyfikującego tam, gdzie nie jest to oczekiwane, ta flaga wskaże ci problematyczne miejsce.Podsumowując - można iść w obie strony, ale trzeba rozumieć konsekwencje.
źródło
Wszystkie instrukcje bazy danych są wykonywane w kontekście transakcji fizycznej, nawet jeśli nie deklarujemy jawnie granic transakcji (BEGIN / COMMIT / ROLLBACK).
Jeśli nie zadeklarujesz jawnie granic transakcji, każda instrukcja będzie musiała zostać wykonana w oddzielnej transakcji (
autocommit
trybie). Może to nawet prowadzić do otwierania i zamykania jednego połączenia na instrukcję, chyba że środowisko może obsłużyć powiązanie połączenia na wątek.Zadeklarowanie usługi jako
@Transactional
zapewni jedno połączenie na cały czas trwania transakcji, a wszystkie instrukcje będą używać tego pojedynczego połączenia izolacyjnego. Jest to o wiele lepsze niż przede wszystkim rezygnacja z jawnych transakcji.W przypadku dużych aplikacji możesz mieć wiele jednoczesnych żądań, a zmniejszenie liczby żądań pozyskania połączenia z bazą danych zdecydowanie poprawi ogólną wydajność aplikacji.
JPA nie wymusza transakcji w operacjach odczytu. Tylko zapisy kończą się wyrzucaniem wyjątku wymaganego przez transakcję na wypadek, gdybyś zapomniał rozpocząć kontekst transakcyjny. Niemniej jednak zawsze lepiej jest zadeklarować granice transakcji, nawet dla transakcji tylko do odczytu (wiosną
@Transactional
umożliwia oznaczanie transakcji tylko do odczytu, co ma dużą zaletę w zakresie wydajności).źródło
Transakcje faktycznie nakładają blokady na bazę danych - dobre silniki bazy danych obsługują współbieżne blokady w rozsądny sposób - i są przydatne w trybie tylko do odczytu, aby zapewnić, że żadna inna transakcja nie dodaje danych, które powodują niespójność widoku. Zawsze chcesz transakcji (chociaż czasami rozsądne jest dostrojenie poziomu izolacji, najlepiej nie robić tego na początku); jeśli nigdy nie piszesz do bazy danych podczas transakcji, zarówno zatwierdzenie, jak i wycofanie transakcji okaże się takie samo (i bardzo tanie).
Teraz, jeśli masz szczęście i Twoje zapytania skierowane do bazy danych są takie, że ORM zawsze mapuje je na pojedyncze zapytania SQL, możesz uciec bez jawnych transakcji, polegając na wbudowanym zachowaniu automatycznego zatwierdzania DB, ale ORM są stosunkowo złożonymi systemami więc nie jest wcale bezpieczne poleganie na takim zachowaniu, chyba że wykonasz dużo więcej pracy, sprawdzając, co faktycznie robi implementacja. Zapisanie wyraźnych granic transakcji jest o wiele łatwiejsze do wykonania (zwłaszcza jeśli można to zrobić za pomocą AOP lub podobnej techniki opartej na ORM; od Java 7 wzwyż można też użyć zasobów próbnych).
źródło
Nie ma znaczenia, czy tylko czytasz, czy nie - baza danych musi nadal śledzić Twój zestaw wyników, ponieważ inni klienci bazy danych mogą chcieć zapisać dane, które zmieniłyby Twój zestaw wyników.
Widziałem wadliwe programy, które zabijały ogromne systemy baz danych, ponieważ tylko czytały dane, ale nigdy nie zatwierdzały, zmuszając dziennik transakcji do wzrostu, ponieważ DB nie może zwolnić danych transakcji przed COMMIT lub ROLLBACK, nawet jeśli klient nic nie zrobił godzinami.
źródło