Brauchen Sie eine databasetransaktion zum Lesen von Daten?

Wenn ich versuche, Daten aus der database zu lesen, zumindest mit

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

Eine Ausnahme sind Würfe, die besagen, dass eine Transaktion nicht vorhanden ist.

Wenn ich die Anmerkung hinzufüge:

 @Transactional( value = SomeClass.TRANSACTIONAL_MANAGER, propagation = Propagation.SUPPORTS, readOnly = true ) 

es funktioniert gut.

Da das Lesen millionenfach pro Sekunde stattfindet, um auf Daten zuzugreifen und sie zu lesen, möchte ich sicherstellen, dass unsere Umgebung nicht unnötig verstopft wird.

Wenn nicht, was kostet das Erstellen einer schreibgeschützten Propagation.Supports Transaktion?

Kann ich in Kombination mit Spring keine Abfrage für den Ruhezustands-Kriterien ohne eine Transaktion erstellen?

Alle databaseanweisungen werden im Kontext einer physischen Transaktion ausgeführt, auch wenn Transaktionsgrenzen nicht explizit deklariert werden (BEGIN / COMMIT / ROLLBACK).

Wenn Sie Transaktionsgrenzen nicht deklarieren, muss jede statement in einer separaten Transaktion ausgeführt werden ( autocommit Modus). Dies kann sogar dazu führen, dass eine Verbindung pro statement geöffnet und geschlossen wird, es sei denn, Ihre Umgebung kann die Verbindung pro Thread verarbeiten.

Wenn Sie einen Dienst als @Transactional , erhalten Sie eine Verbindung für die gesamte Transaktionsdauer, und alle statementen verwenden diese einzelne Isolationsverbindung. Dies ist viel besser, als überhaupt keine expliziten Transaktionen zu verwenden.

In großen Anwendungen haben Sie möglicherweise viele gleichzeitige Anfragen, und die Verringerung der Anforderung zur Verbindungsanforderungsrate für databaseverbindungen wird die Gesamtleistung Ihrer Anwendung definitiv verbessern.

JPA erzwingt keine Transaktionen bei Lesevorgängen. Nur Schreibvorgänge führen dazu, dass eine Ausnahme mit Transaktionsanforderung ausgetriggers wird, falls Sie vergessen, einen Transaktionskontext zu starten. Dennoch ist es immer besser, Transaktionsgrenzen auch für schreibgeschützte Transaktionen zu deklarieren (in Spring @Transactional können Sie schreibgeschützte Transaktionen markieren, was einen großen performancesvorteil hat).

Wenn Sie nun deklarative Transaktionsgrenzen verwenden (z. B. @Transactional ), müssen Sie sicherstellen, dass die Erfassung der databaseverbindung verzögert wird, bis eine JDBC-statement ausgeführt wird. In JTA ist dies das Standardverhalten. Wenn Sie RESOURCE_LOCAL verwenden, müssen Sie die Konfigurationseigenschaft “hibernate.connection.provider_disables_autocommit” festlegen und sicherstellen, dass der zugrunde liegende Verbindungspool so eingestellt ist, dass der automatische Festschreibungsmodus deaktiviert wird.

Gemäß meiner Erfahrung mit der JPA- Implementierung in J2EE wird immer ein Transaktionsmanager benötigt, um die CRUD- Betriebssicherheit zu gewährleisten, indem ein Rollback garantiert wird, um die Datenintegrität zu bewahren.

Unternehmensanwendungen verwenden unterschiedliche Ressourcen, um Daten zu speichern und Nachrichten wie eine database oder Nachrichtenwarteschlange zu senden. Wenn wir diese Ressourcen sequentiell abfragen und die gesamte Operation abbrechen möchten, sobald ein Problem auftritt, müssen wir diese Abfrage in eine Arbeitseinheit einfügen, damit sie als Ganzes ausgeführt wird.

Sie könnten es definieren:

  • durch verwandte Annotationen (wie in den Fragen gezeigt); Auf diese Weise lädt der Container automatisch den Transaktionsmanager für einen bestimmten Persistenzkontext;

  • indem Sie den Transaktionsmanager wie folgt manuell eingeben:

     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 , als JPA-Spec-Implementierung, kann dem gleichen Ansatz folgen.

Weitere Informationen finden Sie in folgendem Artikel: Java_Persistence / Transactions .