2017-01-12 52 views
0

我正在嘗試編寫一個Groovy/Grails 3函數,它查找數據庫對象並鎖定它,然後保存它(自動釋放鎖)。等待Grails事務中的鎖定釋放

如果該函數被多次調用,它應該等到鎖釋放,然後運行更新。我怎樣才能做到這一點?

def updateUser(String name) { 
    User u = User.get(1) 
    // if locked, wait until released somehow? 
    u.lock() 
    u.name = name 
    u.save() 
} 

updateUser('bob') 
updateUser('fred') // sees lock from previous call, waits until released, then updates 
+1

你需要.withNewTransaction做了一個最近的答案找不到它。這裏是一個較舊的http://stackoverflow.com/questions/21805893/handling-grails-transactions-programatically。不要以爲你需要打擾鎖定記錄。將它包裹在.withNewTransaction中。這也意味着如果你直接查詢它 - 你可能需要做同樣的事情...... – Vahid

回答

0

u.save(flush:true)

沖洗Hibernate的Session應該完成交易,並釋放在數據庫級別上的鎖。

0

一般來說,pessimistick locking只適用於transactional context。 因此,請確保將updateUser方法放入使用@Transactional進行註釋的服務中。

調用get(),然後鎖定()將導致2個正在執行的sql語句(一個用於獲取對象,另一個用於鎖定它)。 使用User.lock(),代替發出單個select ... for udpate查詢。

@Transactional 
class UserService { 
    def updateUser(String name) { 
     User u = User.lock(1) // blocks until lock is free 
     u.name = name 
     u.save() 
    } 
}