Hier ist das Problem
Ein Benutzer einer Enterprise-Webanwendung führt eine Aufgabe aus, die zu einer langen (sehr langen) Datenbankabfrage (oder einer anderen langen, die Verarbeitung intensiven Task) führt
Probleme:
Es gibt mehrere Lösungen, die ich entwickelt habe, aber ich bin mir nicht sicher, ob ich weiß, was besser ist (in allen Aspekten, Leistung, Best Practice, Eleganz und Wartbarkeit) und ich würde gerne wissen, was Ihre empfohlene Lösung ist Wenn es eine Lösung gibt, die ich verpasst habe? (wahrscheinlich ja, und viele)
Die schlechte Lösung : Verwenden Sie den Anforderungs-Thread als Arbeitsthread, speichern Sie den Fortschrittsstatus in der Sitzung, lassen Sie einen AJAX-Aufruf den Status (in der Sitzung) in einer anderen parallelen Anforderung überprüfen
Die Kompromisslösung : Erstellen Sie Ihren eigenen Thread-Pool, behandeln Sie einen Überwachungsthread und einen Arbeitsthread und kümmern Sie sich um das Clustering, indem Sie die Status in einem verteilten Transaktions-Cache oder persistenten Speicher synchronisieren. Dadurch wird die Anforderung freigegeben, es werden jedoch Threads erstellt, die dem Anwendungsserver nicht bekannt sind, und sie werden nicht in Deimplementierung geschlossen. Es liegt an Ihnen, Threads sauber zu beenden, und es besteht immer die Möglichkeit, dass Sie etwas verlieren. Dies ist nicht der J2EE-Weg, es zu tun.
Die J2EE-Lösung : Verwenden Sie JMS für die asynchrone Task, das ist es für
die Spring-Lösung : Verwenden Sie Spring batch
Was würden Sie in Ihren Projekten tun / tun? Welche anderen Lösungen kennen Sie? Welche von denen, die ich oben erwähnt habe, ist Ihrer Meinung nach der Gewinner?
Ich würde eine Kombination aus Ihrer sogenannten "schlechten Lösung" und der "j2ee-Lösung" machen:
Der Trick besteht darin, das Anfrage / Antwort-Paar zu vergleichen. Ich würde es so machen:
NULL
als Wert verwendet wird. Übergeben Sie diese ID auch an die Benutzeroberfläche. NULL
ist. Dies ist sauber und gut abstrahiert von jeder konkreten Domäne . Eine rein technische Lösung.
Auch wenn Sie das Polling nicht mögen, ist HTTP statuslos und ich denke, dass die Abfrage nur in genau definierten Intervallen erfolgt.
Wie auch immer, ich habe ein System mit genau diesem Muster implementiert und es läuft gut ...
Die Lösung, die ich vorher benutzt habe, beinhaltet Jetty Cometd anstelle von AJAX. Der Hauptunterschied zwischen Ajax und Cometd ist, dass Cometd mehr von einem Pub / Sub-Modell verwenden kann - der Client (Webbrowser in diesem Fall) abonniert den Publisher (Ihre App) und die App schiebt Updates und Benachrichtigungen an den Webbrowser als an ein Ajax-Modell der konstanten Abfrage des Servers durch den Web-Browser. Sie können die Cometd-Lösung auch dann nutzen, wenn Sie keinen Jetty verwenden - Sie können die Jetty-Jars in den lib-Ordner Ihres jeweiligen Web-Servers legen und es sollte Ihnen gut gehen.
Zeigen Sie dem Benutzer eine Nachricht, dass "Ihre Anfrage akzeptiert wird und es eine Stunde dauern wird, bis sie aktualisiert wird"
Sie erstellen eine Tabelle, die alle diese Transaktionen speichert und diese in einem Stapel auf dem Server verarbeitet.
Der Benutzer muss nicht lange warten und er wird sich freuen, die Nachricht zu sehen. Sie können eine Bestätigungs-E-Mail senden, sobald Ihre Transaktion verarbeitet wurde.
Dies ist die beste Lösung, denke ich.
Wie lange laufen diese Abfragen?
Wenn Sie davon sprechen, dass Sitzungen auslaufen, ist es vielleicht am besten, wenn der Benutzer nicht darauf wartet. Es wird immer lästig sein, wenn der Benutzer 20 Minuten lang auf dem Tab der Abfrage warten muss.
Also, wenn wirklich lange Abfragen der Fall sind, ist es vielleicht am besten, den UI-Ansatz zu ändern und den Benutzer dazu zu bringen, eine Abfrage zu "bestellen", die er später wieder ansieht oder die sogar per Mail benachrichtigt wird .
In einem solchen Fall würde ich die Abfrage in der Datenbank vorbereiten und in einer separaten Tabelle zwischenspeichern. Das heißt, ich würde den Webserver einmal arbeiten lassen, um die Anfrage zu registrieren, eine DB-Aufgabe oder einen separaten Prozess / Server auf Anfragen vorbereiten und den Benutzer benachrichtigen, und dann den Webserver anzeigen lassen, wenn der Benutzer für die zurückkommt Ergebnisse.
Tags und Links web-applications java-ee