транзакции залочить запись на чтение (заставить ждать) или же как иначе мой кейс решается ?
У меня есть кейс что в 1 транзакции одна и та же запись выбирается и делается перезаписывание значения на основе текущего. И получается если получить запись одновременно и обновить её позже то результатом будет то, что выполнится последним
P.S. на скрине ошибка, select должен выполняться for update, но это роли не сыграет
По моей логике если мы выполняем запрос for update,то пока не выполнится обновление она не может быть прочитана
могу лишь сказать, что по логике postgres писатели не блокируют читателей, а читатели не блокируют писателей. select ... for update, в частности, блокирует строки на запись другими запросами, пока не выполнится, но не на чтение. похоже что вы наткнулись на одну из так называемых аномалий сериализации. боюсь, что по вашему скрину и описанию мне сложно понять, на какую именно, но более опытные, наверное, разберутся и подскажут.
Чистый пример транзакции. Мы делаем выборку записи и имеем на этот момент значение 500. Далее +/- 100 и в итоге ожидаем что значение будет 500, а оно 400 по последнему update
А где происходит +/- 100?
Внешне, в коде. На основе наших первых select
При обновлении значение колонки может быть не только значением но и выражением value = value + 100
Хорошо. А если это строка ? value = 'emilly', потом value = 'may'
Как вы ожидаете +100 и -100 если присваиваете явное значение????
Я же говорю, в запросе ошибки нет. Ошибка в логике работы с ней. Мы в коде инкрементируем это значение надеясь что при select будет актуальное. В нашем случае мы выполнили +100 и value стал 600, мы ожидаем что второй запрос будет иметь начальным 600 и мы от туда вычтем 100
Так и почему не написать set value = value +100?
Я понял что с цифрами плохой пример
А зачем вы при таких блокировках выбираете запись, которую будете обновлять — и без FOR UPDATE? Не делайте так. (А ещё лучшэ — поставьте transaction isolation level serializable и не мучайтесь пока с ручными блокировками).
Обсуждают сегодня