7.3.5 Pessimistic and Optimistic Locking 3.1.4

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 7.3.5 Pessimistic and Optimistic Locking - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 3.1.4 ## 7.3.5 Pessimistic and Optimistic Locking #### Optimistic Locking By default GORM classes are configured for optimistic locking. Optimistic locking is a feature of Hibernate which involves storing a version value in a special `version` column in the database that is incremented after each update. The `version` column gets read into a `version` property that contains the current versioned state of persistent instance which you can access:

    def airport = Airport.get(10)println airport.version
When you perform updates Hibernate will automatically check the version property against the version column in the database and if they differ will throw a StaleObjectException. This will roll back the transaction if one is active. This is useful as it allows a certain level of atomicity without resorting to pessimistic locking that has an inherit performance penalty. The downside is that you have to deal with this exception if you have highly concurrent writes. This requires flushing the session:

    def airport = Airport.get(10)try {
        airport.name = "Heathrow"
        airport.save(flush: true)
    }
    catch (org.springframework.dao.OptimisticLockingFailureException e) {
        // deal with exception
    }
The way you deal with the exception depends on the application. You could attempt a programmatic merge of the data or go back to the user and ask them to resolve the conflict. Alternatively, if it becomes a problem you can resort to pessimistic locking. The `version` will only be updated after flushing the session. #### Pessimistic Locking Pessimistic locking is equivalent to doing a SQL "SELECT * FOR UPDATE" statement and locking a row in the database. This has the implication that other read operations will be blocking until the lock is released. In Grails pessimistic locking is performed on an existing instance with the lock method:
    def airport = Airport.get(10)
    airport.lock() // lock for update
    airport.name = "Heathrow"
    airport.save()
Grails will automatically deal with releasing the lock for you once the transaction has been committed. However, in the above case what we are doing is "upgrading" from a regular SELECT to a SELECT..FOR UPDATE and another thread could still have updated the record in between the call to `get()` and the call to `lock()`. To get around this problem you can use the static lock method that takes an id just like get:
    def airport = Airport.lock(10) // lock for update
    airport.name = "Heathrow"
    airport.save()
In this case only SELECT..FOR UPDATE is issued. As well as the lock method you can also obtain a pessimistic locking using queries. For example using a dynamic finder:
    def airport = Airport.findByName("Heathrow", [lock: true])
Or using criteria:
    def airport = Airport.createCriteria().get {
        eq('name', 'Heathrow')
        lock true
    }
| Quick Reference (hide)