Der
php-Editor Youzi bietet Ihnen Java-Fragen und Antworten zur Überwachung des Spring Data JPA-Flusses. Während der Entwicklung ist die Überwachung des Datenflusses in Echtzeit für die Optimierung der Systemleistung und Fehlerbehebung von entscheidender Bedeutung. In diesem Artikel erfahren Sie, wie Sie den JPA-Fluss von Spring Data überwachen, damit Sie den Datenverarbeitungsprozess besser verstehen, Probleme rechtzeitig erkennen und entsprechend behandeln können. Lassen Sie uns besprechen, wie Sie den JPA-Fluss von Spring Data effektiv überwachen und die Systemstabilität und -leistung verbessern können!
Ich versuche, Spring Data JPA-Streaming zu verwenden, wie in diesem Blog erläutert. Allerdings kann ich den Prozess oder Fortschritt nicht mit Protokollen überwachen. Sollte ich im Protokoll mehrere SQL-Abfragen sehen, wenn der Prozess versucht, Daten stapelweise zu extrahieren? Wenn nicht, woher weiß ich dann, dass nicht alle Zeilen auf einmal geladen werden?
Andere Blogs (wie dieser und dieser) schlugen vor, dass ich MySQL in hint_fetch_size
设置为 integer.min_value
konvertieren sollte, was meiner Meinung nach die Lösung sein könnte, aber dies löst die folgende Ausnahme aus:
29.01.2024 14:40:20.843 Warnung 78247 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.sqlexceptionhelper: sql Error: 0, sqlstate: s1000 29.01.2024 14:40:20.843 Fehler 78247 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.sqlexceptionhelper: Streaming-Ergebnissatz com.mysql.cj.protocol.a.result. 4ca63fa5 ist noch aktiv. Es dürfen keine Anweisungen ausgegeben werden, während ein Streaming-Ergebnissatz geöffnet ist und für eine bestimmte Verbindung verwendet wird. Bevor Sie weitere Abfragen versuchen, stellen Sie sicher, dass Sie .close() für alle aktiven Streaming-Ergebnismengen aufgerufen haben. Endzeit: 48 org.springframework.orm.jpa.jpasystemException: Ergebnismenge kann nicht extrahiert werden; verschachtelte Ausnahme ist org.hibernate.Exception.genericjdbceception: Ergebnismenge kann nicht extrahiert werden unter org.springframework.orm.jpa.vendor.hibernatejpadialect.converthibernateaccessException(hibernatejpadialect.java:331)
Das ist mein Repository-Code:
@QueryHints(value = { @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "false"), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_READONLY, value = "true"), }) @Query("SELECT s FROM Salary s") Stream<Salary> findAllStream();
Ich denke, ich würde gerne eine Garantie erhalten, ob die oben genannte Methode die richtige Art ist, Stream-Abfragen in Spring Data JPA zu verwenden, da ich die Leistung des Streamings selbst nicht zuverlässig überwachen kann?
Aktualisiert
Die obige Ausnahme tritt aufgrund wiederholter Aufrufe der findallstream-Methode in derselben aufrufenden Methode auf. Durch das Entfernen einer davon wurde die Ausnahme behoben.
Ich kann keine Protokollkonfiguration finden, die anzeigt, ob die Daten stapelweise abgerufen werden. Aber ich habe eine Möglichkeit gefunden, die Leistung lokal zu testen.
Um die Streaming-Funktionalität zu testen, muss ich auf eine Datenbank zugreifen, die Millionen von Datensätzen enthält. Ich verwende das Docker-Image https://www.php.cn/link/7092d5eb1bbca1a22bdc69ba3f517e68, um MySQL-Mitarbeiterdaten zu verwenden
Nachdem ich das Docker-Image eingerichtet habe, habe ich Probleme, MySQL Workbench mit dem Server zu verbinden. Es sieht so aus, als ob das Docker-Image standardmäßig nicht für die Annahme von SSL-Verbindungen konfiguriert ist. Ich musste das use ssl
-Flag deaktivieren, um die Verbindung herzustellen. Diese Einstellung wird in der MySQL-Workbench auf der Registerkarte „SSL“ angezeigt.
Der Verbindungsstring in der Anwendung muss außerdem wie folgt konfiguriert sein:
spring.datasource.url=jdbc:mysql://localhost:3307/employees?verifyservercertificate=false&usessl=false&requiressl=false
Die Daten in der Mitarbeiterdatenbank bestehen aus einer Tabelle mit dem Namen salaries
, die etwa 2,8 Millionen Zeilen enthält.
Zum Testen habe ich eine kleine Spring Data JPA-Anwendung geschrieben, die die folgenden Methoden in der Repository-Klasse und einen einfachen Controller zum Aufrufen dieser Methoden enthält:
@Override List<Salary> findAll(); @QueryHints(value = { @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "false"), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_READONLY, value = "true"), }) @Query("SELECT s FROM Salary s") Stream<Salary> findAllStream();
Ich habe dann einen kleinen Code geschrieben, der die gelesenen Daten in ein JSON-Objekt konvertierte und es dann mithilfe mehrerer Threads zurück in die Datei schrieb. Dies dient dazu, die Verarbeitung in realen Fällen zu simulieren.
Das habe ich beobachtet.
Der Speicherverbrauch erhöht sich erheblich, wenn die Listenmethode verwendet wird. Die erste Abfrage nahm die meiste Zeit in Anspruch, aber sobald alle Daten geladen waren, war die eigentliche Datenverarbeitung schnell abgeschlossen.
Bei Verwendung der Stream-Methode sind die Auswirkungen auf die Speichernutzung nahezu unmerklich. Insgesamt ist die Leistung des Vervollständigungsverarbeitungsteils jedoch ähnlich oder sogar schlechter als bei der Listenmethode.
Fazit
Meine obigen Erkenntnisse lassen mich zu dem Schluss kommen, dass der Repository-Ansatz stream
返回类型仅应在存在内存不足风险时使用,即获得 out 内存异常
ist. Andernfalls, wenn Ihre Anwendung bereits auf einem ausreichend großen Server ausgeführt wird, sind die Gesamtauswirkungen auf die Speichernutzung kaum spürbar und nur vorübergehend, wenn Ihr Prozess schnell abgeschlossen wird.
Speichernutzungsstatistiken vom Intellij Profiler
Das obige ist der detaillierte Inhalt vonSo überwachen Sie Spring Data JPA-Streams. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!