Hallo,
habe ein Problem ähnlich diesem hier:
http://www.java-forum.org/data-tier/103607-jpa-pessimistic-lock-funktioniert.html
(hatte auch schonmal sowas gefragt, aber da kamen irgendwie keine Antworten, die mir weitergeholfen haben).
Also als Beispiel (welches auch der praktischen Anwendung recht nahe kommt), soll ein Zähler implementiert werden, und in der Webanwendung gibts einfach einen Button, um diesen um eins zu erhöhen. Also lesen, +1, wieder schreiben. Nun kanns ja sein, dass da zwei Zugriffe quasi gleichzeitig kommen. Dann hat man wohl die "der letzte gewinnt"-Situation:
Transaktion 1 liest Wert (14), dann liest Transaktion 2 den gleichen Wert, T1 schreibt (15), T2 schreibt auch (15). Wobei der korrekte Wert für T2 allerdings 16 wäre.
Man müsste diese Zugriffe nun also, ganz klassischen wie Methoden, synchronisieren. Das so zu machen wäre auch der letzte Notnagel, aber eigentlich ist es das Ziel, das in der Datenbank zu synchronisieren.
Habs nun soweit hinbekommen, die Entity-Klasse "versioned" zu machen, was anscheinend notwendig ist, damit entityManager.lock(...) überhaupt funktioniert. Nun gut. Damit kann man den erwähnten Fall immerhin verhindern, bei T2 wird dann eine Exception geworfen, die man auch brav abfangen und auswerten kann. Hilft aber auch nur halb weiter, denn T2 soll ja einen Wert (16) bekommen. Für die Funktionsweise der Anwendung ist es notwendig, dass der Prozess, der T2 aufruft, mit dem korrekten Wert weiterarbeitet. Einfach nur der Hinweis "sorry fehlgeschlagen" ist nutzlos.
Was also tun? In einer Endlosschleife die Transaktion so lange aufrufen und Exceptions abfangen, bis es endlich mal klappt (was in den allermeisten Fällen beim ersten Mal der Fall sein dürfte, aber es muss halt SICHER sein)?
Gibts da irgendwelchen SQL- oder JPA-Code für, der die Transaktionen quasi hintereinander reiht? Würde es helfen, für die Datenbank (PostgreSQL 8.4, die ist bei sowas wohl recht leistungsfähig) eine stored procedure in java zu schreiben, die sowas dann automatisch erledigt? Oder wie macht man das !?
Ich meine, der Anwendungsfall ist ja nun nicht gerade exotisch.. sowas gibts doch andauernd. Da muss es doch irgendeine Standardlösung für geben!
Und das im Programm zu synchronisieren ist keine gute Lösung, weil es möglich sein soll, mit mehreren Servern gleichzeitig auf die Datenbank zuzugreifen.
Gruß+Danke
Jan
habe ein Problem ähnlich diesem hier:
http://www.java-forum.org/data-tier/103607-jpa-pessimistic-lock-funktioniert.html
(hatte auch schonmal sowas gefragt, aber da kamen irgendwie keine Antworten, die mir weitergeholfen haben).
Also als Beispiel (welches auch der praktischen Anwendung recht nahe kommt), soll ein Zähler implementiert werden, und in der Webanwendung gibts einfach einen Button, um diesen um eins zu erhöhen. Also lesen, +1, wieder schreiben. Nun kanns ja sein, dass da zwei Zugriffe quasi gleichzeitig kommen. Dann hat man wohl die "der letzte gewinnt"-Situation:
Transaktion 1 liest Wert (14), dann liest Transaktion 2 den gleichen Wert, T1 schreibt (15), T2 schreibt auch (15). Wobei der korrekte Wert für T2 allerdings 16 wäre.
Man müsste diese Zugriffe nun also, ganz klassischen wie Methoden, synchronisieren. Das so zu machen wäre auch der letzte Notnagel, aber eigentlich ist es das Ziel, das in der Datenbank zu synchronisieren.
Habs nun soweit hinbekommen, die Entity-Klasse "versioned" zu machen, was anscheinend notwendig ist, damit entityManager.lock(...) überhaupt funktioniert. Nun gut. Damit kann man den erwähnten Fall immerhin verhindern, bei T2 wird dann eine Exception geworfen, die man auch brav abfangen und auswerten kann. Hilft aber auch nur halb weiter, denn T2 soll ja einen Wert (16) bekommen. Für die Funktionsweise der Anwendung ist es notwendig, dass der Prozess, der T2 aufruft, mit dem korrekten Wert weiterarbeitet. Einfach nur der Hinweis "sorry fehlgeschlagen" ist nutzlos.
Was also tun? In einer Endlosschleife die Transaktion so lange aufrufen und Exceptions abfangen, bis es endlich mal klappt (was in den allermeisten Fällen beim ersten Mal der Fall sein dürfte, aber es muss halt SICHER sein)?
Gibts da irgendwelchen SQL- oder JPA-Code für, der die Transaktionen quasi hintereinander reiht? Würde es helfen, für die Datenbank (PostgreSQL 8.4, die ist bei sowas wohl recht leistungsfähig) eine stored procedure in java zu schreiben, die sowas dann automatisch erledigt? Oder wie macht man das !?
Ich meine, der Anwendungsfall ist ja nun nicht gerade exotisch.. sowas gibts doch andauernd. Da muss es doch irgendeine Standardlösung für geben!
Und das im Programm zu synchronisieren ist keine gute Lösung, weil es möglich sein soll, mit mehreren Servern gleichzeitig auf die Datenbank zuzugreifen.
Gruß+Danke
Jan