Frage

Lassen Sie uns sagen, dass ich eine Zählerfunktion haben, die einen Zähler mit rohen SQL aktualisiert:

 public void updateCounter() {
   executeSql("UPDATE counter SET count_value = count_value + 1 WHERE id = 1;");
 }

Die Datenbank würde sicherstellen, dass zwei gleichzeitige Anrufe an den Zähler behandelt werden wie erwartet -., Dass alle Anrufe den Zähler mit einem Zuwachs und kein Updates würde verloren gehen aktualisieren würden

Anstatt diese Ausführung durch einen rohen SQL-Befehl Ich mag GORM verwenden. Die naive Art und Weise zu tun, es wäre etwas entlang der Linien der folgenden sein:

 public void updateCounter() {
   Counter c = Counter.get(1)
   c.countValue += 1
   c.save()
 }

In diesem Fall würde ich davon ausgehen, dass ein Update verloren gehen könnte, wenn zwei Threads die updateCounter () -Methode im selben Moment nennen. Was ist die richtige "Grails / GORM-way" diese Gleichzeitigkeit Problem zu behandeln?

War es hilfreich?

Lösung

Sie können entweder ‚pessimistisch‘ oder ‚optimistisch‘ Sperrstrategien verwenden, die sowohl von Hibernate unterstützt und daher von GORM. Die Standard-GORM Strategie ist ‚optimistisch‘ (die die Version Spalte / Eigenschaft der persistenten Domäne Entität verwendet, standardmäßig erstellt). Es könnte wie folgt verwendet werden:

...
try {
 Counter c = Counter.get(1)
 c.countValue += 1
 c.save(flush:true)
}
catch(org.springframework.dao.OptimisticLockingFailureException e) {
// deal with concurrent modification here
}
...

Wenn Sie die ‚pessimistische‘ Locking-Strategie bevorzugen statt (die blockiert alle anderen gleichzeitig liest, btw), können Sie es tun könnte explizite ‚lock‘ GORM Meta-Methode verwendet, etwa so:

...
Counter c = Counter.lock(1) //lock the entire row for update
c.countValue += 1
c.save(flush:true) //GORM will autorelease the lock once the TX is committed
...

Hope, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top