Czy potrzebujesz transakcji bazodanowej do odczytu danych?

Kiedy próbuję odczytać dane z bazy danych, przynajmniej używając

((Session)em.getDelegate()).createCriteria()

Wyjątkiem jest rzut mówiący, że transakcja nie jest obecna.

Kiedy dodam adnotację:

@Transactional(
    value = SomeClass.TRANSACTIONAL_MANAGER, 
    propagation = Propagation.SUPPORTS, 
    readOnly = true
)
Działa dobrze.

Jednakże, ponieważ odczyt będzie się zdarzał milion razy na sekundę, aby uzyskać dostęp do danych i je odczytać, chcę mieć pewność, że nasze środowisko nie zostanie niepotrzebnie zapchane.

Jeśli nie, jaki jest koszt utworzenia transakcji tylko do odczytu Propagation.Supports?

Czy nie mogę utworzyć zapytania Hibernate Criteria bez transakcji, w połączeniu z Springiem?

Author: Vlad Mihalcea, 2014-10-12

2 answers

Wszystkie polecenia bazy danych są wykonywane w kontekście fizycznej transakcji, nawet jeśli nie deklarujemy wyraźnie granic transakcji (BEGIN/COMMIT/ROLLBACK).

Jeśli nie zadeklarujesz granic transakcji, wtedy każde polecenie będzie musiało zostać wykonane w oddzielnej transakcji (Trybautocommit). Może to nawet prowadzić do otwarcia i zamknięcia jednego połączenia dla każdej instrukcji, chyba że środowisko może poradzić sobie z powiązaniem connection-per-thread.

Deklarowanie usługi ponieważ @Transactional daje jedno połączenie przez cały czas trwania transakcji, a wszystkie polecenia będą używać tego pojedynczego połączenia izolacyjnego. Jest to o wiele lepsze niż nie używanie jawnych transakcji w pierwszej kolejności.

W przypadku dużych aplikacji możesz mieć wiele jednoczesnych żądań, a zmniejszenie szybkości żądania akwizycji połączenia z bazą danych zdecydowanie poprawi ogólną wydajność aplikacji.

JPA nie wymusza transakcji przy operacjach odczytu. Tylko pisze end do wyrzucenia transakcji wymagany wyjątek w przypadku, gdy zapomnisz rozpocząć kontekst transakcji. Niemniej jednak, zawsze lepiej jest deklarować granice transakcji nawet dla transakcji tylko do odczytu (w Spring @Transactional umożliwia zaznaczanie transakcji tylko do odczytu, co ma wielką zaletę wydajności).

Teraz, jeśli używasz deklaratywnych granic transakcji (np. @Transactional), Musisz upewnić się, że przejęcie połączenia z bazą danych jest opóźnione do czasu wykonania instrukcji JDBC. W JTA, to jest domyślne zachowanie. Podczas korzystania z RESOURCE_LOCAL musisz ustawić hibernate.connection.provider_disables_autocommit właściwość konfiguracyjna i upewnij się, że podstawowa Pula połączeń jest ustawiona tak, aby wyłączyć tryb automatycznego zatwierdzania.

 69
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 09:01:14

Zgodnie z moim doświadczeniem z JPA implementacją w J2EE, Menedżer transakcji {3]} jest zawsze potrzebny do zapewnienia bezpieczeństwa operacji CRUD , gwarantując wycofanie w celu zachowania integralności danych.

Aplikacje korporacyjne używają różnych zasobów do zapisywania danych i wysyłania wiadomości, takich jak Baza Danych lub Kolejka wiadomości. Jeśli chcemy przeszukać te zasoby sekwencyjnie i anulować całą operację po wystąpieniu problemu, trzeba umieścić to zapytanie w jednostce pracy tak, że będzie wykonywane jako całość.

Można go zdefiniować:

  • W ten sposób kontener automatycznie ładuje menedżera transakcji dla danego kontekstu trwałości;

  • Poprzez ręczne wstrzyknięcie menedżera transakcji, w następujący sposób:

    public class sample {
    
        @PersistenceContext
        EntityManager em;
    
        // Injected transaction manager
        @Inject
        UserTransaction utx;
    
        private static final String[] GAME_TITLES = {
            "Super Mario Brothers",
            "Mario Kart",
            "F-Zero"
        };
    
        private void clearData() throws Exception {
            utx.begin();
            em.joinTransaction();
            System.out.println("Dumping old records...");
            em.createQuery("delete from Game").executeUpdate();
            utx.commit();
        }
    
        private void insertData() throws Exception {
            utx.begin();
            em.joinTransaction();
            System.out.println("Inserting records...");
            for (String title : GAME_TITLES) {
                Game game = new Game(title);
                em.persist(game);
            }
            utx.commit();
            // clear the persistence context (first-level cache)
            em.clear();
        }
    
        // ...
    
    }
    

Spring Data , jako implementacja JPA-spec, może następować tak samo podejdźcie.

Możesz znaleźć więcej informacji, czytając poniższy artykuł: Java_persystencja / transakcje.

 1
Author: vdenotaris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-12 16:54:00