2009-03-05 4 views
2

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

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 - das ist alles Anrufe würden den Zähler mit einem Inkrement aktualisieren und keine Updates würden verloren gehen.

Anstatt dies durch Ausgabe eines Raw SQL-Befehls auszuführen, möchte ich GORM verwenden.

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: Die naive Art und Weise, es zu tun etwas entlang der Linien von wäre. Was ist der korrekte "Grails/GORM-Weg", um dieses Nebeneinanderproblem zu lösen?

Antwort

6

Sie können entweder 'pessimistische' oder 'optimistische' Sperrstrategien verwenden, die beide von Hibernate und daher von GORM unterstützt werden. Die Standard-GORM-Strategie ist "optimistisch" (verwendet die Versionsspalte/Eigenschaft der persistenten Domänenentität, die standardmäßig erstellt wird). 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 statt bevorzugen (die blockiert alle anderen gleichzeitig liest, btw), können Sie es explizite ‚lock‘ GORM Meta-Methode tun könnte, wie folgt:

... 
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 
... 

Hoffe, das hilft.

+0

was meinst du, wenn du sagst "Deal mit gleichzeitiger Modifikation hier"? Sie meinen, eine "Zusammenführung" oder was sonst noch zu verwenden? Prost – Mulone