Блокировка в Grails не работает - PullRequest
1 голос
/ 29 июня 2011

Я сталкиваюсь с некоторыми проблемами при использовании замка в Grails.

Ситуация следующая:

У меня есть класс User, а затем другой класс UserProperty, который имеет свойство belognsTo = User.

Теперь, чтобы избежать одновременного изменения пользователем этих свойств, я хочу заблокировать пользователя, а после этого изменить / добавить / удалить новые свойства.

Но блокировка, похоже, не работает, поскольку в обоих случаях запрос проходит через него. Псевдокод выглядит примерно так:

User.lock(userId)
log.info "Starting modifiying properties"
addRemoveOrChangePropertiesToUser(userId)
log.info "Finsih modifing properties"
User.save(flush: true)

Я ожидаю поведения, когда первый запрос проходит и регистрирует все. И до этого (поскольку пользователь заблокирован) второй запрос ждет, а затем вносит изменения в свойства.

Основываясь на файлах журнала, я вижу совершенно другое поведение. Оба запроса обрабатываются без какого-либо времени ожидания (почти одновременно).

У вас есть идея, что я делаю не так? Я неправильно понял некоторые концепции, связанные с блокировкой БД? Как мне добиться желаемого поведения?

Спасибо, Nicolas

Ответы [ 3 ]

4 голосов
/ 05 марта 2013

Я только что столкнулся с подобной проблемой, когда моя функция была в контроллере.Я думал, что другие потоки должны быть заблокированы после попадания в оператор .lock, но этого не произошло.Завершение всего этого в транзакции решило проблему для меня.

Так что-то вроде этого:

User.withTransaction {
    User.lock(userId)
    log.info "Starting modifiying properties"
    addRemoveOrChangePropertiesToUser(userId)
    log.info "Finsih modifing properties"
    User.save()
}

Оглядываясь назад, я думаю, это имеет смыслЯ подозреваю, что транзакция должна обеспечить четкое разграничение (единицу работы), иначе как GORM / hibernate узнает, когда он может снять блокировку?

Методы контроллера имеют открытый сеанс, но не включены в транзакцию.Методы обслуживания по умолчанию включены в транзакцию, и я подозреваю, что мы не увидим эту проблему там.

0 голосов
/ 29 июня 2011

Я не уверен, что так работает замок.Насколько я понимаю, он блокирует сущность от ДРУГИХ, обновляющих тот же экземпляр, когда они получают его из сеанса гибернации.

0 голосов
/ 29 июня 2011

Я не уверен, что вы реализуете это правильно. Я думаю, вам нужно получить экземпляр, а затем заблокировать его как ...

def instance = Thing.get(1)
instance.lock()

А затем попытайтесь изменить заблокированный экземпляр.

...