2010-12-29 19 views
0

Ich habe eine bestimmte Ressource, auf die ich den Zugriff beschränken möchte. Im Grunde benutze ich eine Session-Level-Sperre. Es wird jedoch immer mühsam, JavaScript zu schreiben, das alle möglichen Arten des Schließens eines Fensters abdeckt.Wie richte ich eine Sperre ein, bei der automatisch eine Zeitüberschreitung auftritt, wenn das Signal nicht erhalten bleibt?

Sobald der Benutzer diese Seite verlässt, möchte ich die Ressource entsperren.

Meine Grundidee ist es, eine Art Server-Timeout zu verwenden, um die Ressource zu entsperren. Wenn ich die Ressource nicht freischalten kann, möchte ich einen Timer aktivieren und die Ressource entsperren.

Zum Beispiel, nach 30 Sekunden mit jetzt von der Clientseite aktualisieren, entsperren Sie die resoce.

Meine grundlegende Frage ist, welche Art von Seitentrick kann ich verwenden, um dies zu tun? Es ist mein Verständnis, dass ich nicht einfach einen Thread in JSF erstellen kann, weil es nicht verwaltet werden würde.

Ich bin sicher, dass andere Leute diese Art von Sache tun, was ist die richtige Sache zu verwenden?

Danke, Grae

+0

Auf welcher Ebene möchten Sie den Zugriff beschränken? Einmal pro eingeloggten Benutzer? – BalusC

+0

Wäre einer von diesen nützlich? http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/package-summary.html Ich denke an die geplante Future, aber ich bin mir nicht sicher, ob J2EE dies hat. – Piskvor

+0

@BalusC Eine nicht thread-sichere resouce. Der Benutzer kann die Ressource nur verwenden, wenn er sie nicht bereits verwendet. –

Antwort

1

Als BalusC richtig voll gefragt, ist die große Frage, auf welcher Ebene der Granularität möchten Sie diese Verriegelung tun? Per eingeloggten Benutzer, für alle Benutzer, oder vielleicht könnten Sie mit der Sperrung pro Anfrage durchkommen?

Oder, und das wird ein härterer, ist die Idee, dass eine einzelne Seite Anfrage das Schloss ergreift und dann diese bestimmte Seite soll die Sperre zwischen Anfragen halten? Z.B. als eine Art Reservierung. Ich blättere auf einer Hotelseite, und wenn ich mir nur ein Zimmer anschaue, habe ich eine implizite Reservierung im System für dieses Zimmer gemacht, damit es nicht passieren kann, dass jemand anderes den Raum für echte reserviert, während ich es ansehe?

Im letzteren Fall, vielleicht wäre das folgende Schema arbeiten:

  1. Im Anwendungsbereich, eine globale gleichzeitige Karte definieren.
  2. Schlüssel der Karte stellen die Ressourcen dar, die Sie schützen möchten.
  3. Werte der Karte sind eine benutzerdefinierte Struktur, die eine Schreibsperre (z. B. ReentrantReadWriteLock), ein Token und einen Zeitstempel enthalten.
  4. Im Anwendungsbereich gibt es auch eine einzige globale Sperre (z. B. ReentrantLock)
  5. Code in einer Anforderung zunächst die globale Sperre und überprüft schnell, ob der Eintrag in der Karte vorhanden ist.
  6. Wenn der Eintrag vorhanden ist, wird er übernommen, andernfalls wird er erstellt. Die Erstellungszeit sollte sehr kurz sein. Die globale Sperre wird schnell freigegeben.
  7. Wenn der Eintrag neu war, wird er über seine Schreibsperre gesperrt, und ein neues Token und ein neuer Zeitstempel werden erstellt.
  8. Wenn der Eintrag nicht neu war, ist er über seine Lesesperre
  9. gesperrt, wenn der Code das gleiche Token hat, kann er fortfahren und auf die geschützte Ressource zugreifen, andernfalls prüft er den Zeitstempel.
  10. Wenn der Zeitstempel abgelaufen ist, versucht es, die Schreibsperre zu greifen.
  11. Die Schreibsperre hat eine Zeitüberschreitung. Wenn die Auszeit auftritt, geben Sie etwas auf und teilen Sie dem Kunden etwas mit. Andernfalls werden ein neues Token und ein neuer Zeitstempel erstellt.

Dies ist nur die allgemeine Idee. In einer Java EE-Anwendung, die ich erstellt habe, habe ich etwas Ähnliches verwendet (obwohl nicht genau dasselbe) und es hat ziemlich gut funktioniert.

Alternativ könnten Sie auch einen Quarzauftrag verwenden, der die veralteten Einträge in regelmäßigen Abständen entfernt. Eine weitere Alternative dafür ist das Ersetzen der globalen gleichzeitigen Karte durch z. eine JBoss Cache- oder Infinispan-Instanz. Diese erlauben es Ihnen, eine Räumungsrichtlinie für ihre Einträge zu definieren, so dass Sie diese nicht selbst programmieren müssen. Wenn Sie diese Caches noch nie benutzt haben, kann es schwieriger sein, sie einzurichten und richtig zu konfigurieren, als nur einen einfachen Quarzjob zu erstellen.

+0

Ich mag Ihre allgemeine Idee. Kein zusätzlicher Aufwand, überprüfen Sie einfach den Zeitstempel, wenn eine neue Anfrage auftritt. –