Пессимистическая блокировка в Grails 3+ lock()

    def check(){
        println"start first"
        Domain1 domain1=Domain1.get(1);
        domain1.lock();
        println "locking started"
        sleep(20*60)
        println "save first"
        domain1.name="hari ram"
        domain1.save();
        println "save first completed"

    }
    def check2(){
        try {
            println"start second"
            Domain1 domain1=Domain1.get(1);
            println"save second"
            domain1.name="hari ram -------------------++++++++"
            domain1.save(flush:true,failOnError:true);
            println "save second completed"
        }
        catch(Exception ex){
            ex.each{
                println "error ${ex}"
            }
        }
    }

Мой журнал из приведенного выше кода:

start first
locking started
start second
save second
save second completed
save first
save first completed

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


person ujjwol shrestha    schedule 24.08.2017    source источник
comment
многого не хватает, начните с stackoverflow.com/questions/9301395/   -  person V H    schedule 24.08.2017
comment
@vahid тоже пробовал смывать   -  person ujjwol shrestha    schedule 24.08.2017
comment
Я думаю, вы многого не понимаете. Я думаю, что метод блокировки предназначен для работы внутри цепочки транзакций - что-то вызывает, что-то блокирует, что-то делает, возвращает блокировку проверки и так далее, все это часть одной и той же транзакции, но, очевидно, более сложная, чем вы себе представляли выше. Тот факт, что вы делаете что-то 1 место, а затем вызываете другое transactional - трудно понять, поскольку все вышеперечисленное выглядит как вызов контроллера, и на этот раз выдает сброс: true - говорит ему, что он должен это сделать   -  person V H    schedule 24.08.2017


Ответы (1)


Вы звоните check и check2 из одного и того же сеанса? Метод lock() выбирает строку для обновления (на уровне БД), но если вы входите в тот же сеанс и пытаетесь получить тот же объект, вы должны получить его из сеанса гибернации, а не обращаться к базе данных и иметь дождитесь освобождения строки.

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

person Trebla    schedule 24.08.2017
comment
хорошо, я вызвал check1 из одного браузера и check2 из другого браузера, мне нужно только заблокировать строку. - person ujjwol shrestha; 24.08.2017