2016-08-08 4 views
2

(Ich werde Groovy/Grails Syntax in Probe verwenden)Gibt es eine Möglichkeit, den Unternehmenswert in Hibernate/Grails zu aktualisieren, ohne aus der Datenbank erfrischenden

In Hibernate, wenn ein Unternehmen geladen wird, sie auf dem gehalten werden Session-Cache/L1, das Problem ist, dass sie nicht referenziert werden, wenn sie außerhalb der Sitzung geändert werden, auch wenn ich sie über GORM-Methoden abfrage. Deshalb verwende ich refresh().

(Alle folgenden Aussagen sind in einer Sitzung durchgeführt.)

User.withNewTransaction { 
    User user = User.findById(1L, [lock: true]) //select for update 
    user.name='new name' 
    user.save() 
} 

//user entity gets updated on a different thread. 

User.withNewTransaction { 
    user = User.findById(1L, [lock: true]) //another select for update 
    //at this point, the user entity is not yet filled in with the updated values from the different thread 
    //so I'm forced to do a refresh so that the user will have the correct values 
    user.refresh() 
    //update user 
} 

Gibt es eine Alternative dazu?

Das bedeutet, ich muss zweimal abfragen, um sicherzustellen, dass wir den richtigen Wert für die zweite Transaktion haben.

Antwort

-1

Ja.

einfach fallen die refresh:

User.withNewTransaction { 
    user = User.findById(1L) //user = User.findById(1L, [lock: true]) //another select for update 
    //at this point, the user entity is not yet filled in with the updated values from the different thread 
    //so I'm forced to do a refresh so that the user will have the correct values 
    //user.refresh() 
    //update user 
} 

Eine bessere Lösung ist es, die Transaktion zu fallen! da Transaktionen für Batch Operationen verwendet werden:

user = User.findById(1L) 

Wenn Sie die Transaktion Syntax halten wollen, dann macht es mehr Sinn, es zu anderen laufenden Transaktionen zu verbinden mit withTransaction:

User.withTransaction { 
     user = User.findById(1L) //user = User.findById(1L, [lock: true]) //another select for update 
     //at this point, the user entity is not yet filled in with the updated values from the different thread 
     //so I'm forced to do a refresh so that the user will have the correct values 
     //user.refresh() 
     //update user 
    } 

Summery:

Sie sollten selten refresh verwenden, da es ign ist Erze Hibernate Vorteile, es sei denn, es gibt eine spezielle Anforderung here

+0

Wenn ich den Refresh-Aufruf entfernen, wird der Wert für den Benutzer möglicherweise veraltet. Aufgrund anderer Threads möglich, es zu modifizieren. Ich muss die Transaktionsblöcke aufgrund einer bestimmten Anforderung verwenden. – froi

+0

Wir müssen sperren, damit andere Threads die Einheit, die wir gerade ändern, nicht berühren. In Bezug auf, mischen mit Sperren und direkt holen, ich bin mir nicht sicher, ob ich verstehe. Meinst du Skip Hibernate und nur native SQL verwenden? Kannst du bitte darlegen? – froi

Verwandte Themen