4.1 Transakcje i integralność bazy danych

Normalnym trybem działania bazy danych jest otrzymywanie co minutę tysięcy żądań od setek różnych klientów. W takim przypadku często dochodzi do sytuacji, gdy te same dane są uzyskiwane z różnych zapytań.

Rzadziej, ale znowu od czasu do czasu zdarzają się sytuacje, gdy jedno żądanie odczytuje określoną linię, a inne żądanie jednocześnie ją zmienia. Wyobraź sobie, co się stanie, jeśli ktoś przeczyta wiersz, który jest tylko w połowie zmieniony? Nic dobrego.

Problem ten rozwiązuje się na kilka sposobów. Po pierwsze, możesz po prostu zablokować linię, która się zmienia. Zarówno do czytania, jak i do pisania. Ta metoda działa, ale prędkość bazy bardzo cierpi.

Drugim sposobem jest zablokowanie łańcucha tylko do zapisu. Jednak nadal będzie problem, gdy ktoś spróbuje odczytać częściowo zmodyfikowaną linię. Wniosek - nie powinno być sytuacji, w której linia zostanie częściowo zmieniona.

Dlatego wymyślili trzecią metodę - transakcje. Transakcja to grupa działań, które są wykonywane albo wszystkie razem, albo wcale. Nie może być sytuacji, że część czynności została wykonana, a część nie. Jeśli nie jest możliwe dokonanie wszystkich zmian, wszystkie zmiany, które już zostały wprowadzone, są wycofywane.

Każdy nowoczesny serwer SQL umożliwia zmianę danych tylko w transakcjach. Otwierasz transakcję, wprowadzasz zmiany w dowolnej liczbie tabel i zatwierdzasz transakcję. Następnie SQL Server próbuje wprowadzić zmiany. Jeśli wszystko jest w porządku, zostaną dodane do ogólnej bazy danych. Jeśli wystąpiły problemy, wszystkie zmiany zostaną anulowane.

Hibernate również używa tego paradygmatu. Dlatego na poprzednim wykładzie widzieliśmy, że przy próbie zapisania obiektu Pracownik do bazy najpierw otwierana była transakcja, a po zapisaniu zatwierdzana.

Zajmiemy się tym tematem bardziej szczegółowo, ale na razie po prostu wiedz, dlaczego transakcje są potrzebne i gdzie są zwykle używane.

4.2 Zdobywanie przedmiotów

Jeśli Hibernate wykonuje żądanie pobrania danych, nie ma potrzeby jawnego otwierania transakcji. Sam Hibernate zrobi to, jeśli uzna to za stosowne: ma swoje ustawienia, a także ustawienia serwera SQL.

Przeanalizujemy, jak pracować z bazą danych. A najprostszym z nich jest pobieranie obiektu według jego identyfikatora . Aby to zrobić, użyj metody get()na obiekcie sesji . Ogólna forma takiego żądania:

Class Name = session.get(Class.class, ID);

Przykład:

public User getUserById(Integer id) {
    try (Session session = sessionFactory.openSession()) {
        User user = session.get(User.class, id);
        return user;
    }
}

4.3 Zapisywanie (dodawanie) obiektów

Jeśli chcesz zapisać swój obiekt do bazy danych, wówczas zostanie wykonane zapytanie na poziomie SQLWSTAWIĆ. Dlatego twoje działania muszą być wykonywane jako oddzielna transakcja. Ponadto lepiej jest użyć metody persist()obiektu sesji dla trwałości .

Ogólna forma takiego żądania:

session.persist(An object);

Metoda persist()zmienia nie tylko podłoże, ale także sam obiekt. Rzecz w tym, że kiedy dodajemy obiekt do bazy danych, to obiekt ten nie ma jeszcze własnego identyfikatora przed dodaniem . Cóż, zwykle tak, chociaż są niuanse. A po dodaniu obiekt ma już ID .

public boolean saveUser(User user) {
    try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
            session.persist(user);
            transaction.commit();
            return true;
    }
    catch() {
    return false;
   	}
}

Obiekt Session posiada również metodę save()wykonującą podobną funkcję. Po prostu metoda save()jest starym standardem Hibernate, a metoda persist()jest standardem JPA.

4.4 Usuwanie obiektów

Jeśli chcesz usunąć istniejący obiekt, jest to bardzo łatwe. Aby to zrobić, obiekt sesji ma specjalną metodę - remove().

Ogólna forma takiego żądania:

session.remove(An object);

I oczywiście napiszmy kod z przykładem:

public boolean removeUser(User user) {
    try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
            session.remove(user);
            transaction.commit();
            return true;
    }
    catch() {
    return false;
   	}
}

Dlaczego to takie trudne, pytasz?

Cóż, po pierwsze, wszelkie zmiany w bazie danych zawsze mają inne i nie zawsze oczywiste konsekwencje. Po drugie, z tym obiektem mogą być powiązane obiekty podrzędne itp. Scenariusze usuwania są więc często nietrywialne.