Войти

Показать полную графическую версию : Изоляция, SELECT FOR UPDATE


evpu
25-02-2019, 10:16
Добрый день!

Оптимизирую код, вычищал места где запросы проходят не атомарно.
К примеру, есть основная таблица аккаунтов, есть гостевая. Переделываю в связи с ОЧЕНЬ большим количеством параллельных потоков, и высокой вероятностью обращения к одному иденту из разных потоков.
UPDATE main_acc SET balance=(balance-"tarif") WHERE id="XXXX" //это главная таблица
UPDATE guest_acc SET balance = (SELECT balance FROM main_acc WHERE id="XXXX" LIMIT 1 FOR UPDATE) WHERE main_id="XXXX" //это "альтернативные локации"

Тарификация, короче.
Было иначе, сначала считывал, потом обновлял.
И тут возник вопрос, а что будет, если другой поток спросит SELECT id FROM main_acc WHERE hex_ident="HEX" - к слову, поле hex_ident не является первичным, но является уникальным.
Если строка в этот момент будет в блокировке, то что произойдет? Будет ждать освобождения строки, надеюсь???
Т.е если под критерий SELECT...WHERE попадают строки находящиеся в блокировке, они не исключаются из выборки? А то чревато ложным появлением ситуации "account not found" со всеми вытекающими прискорбными последствиями

Iska
25-02-2019, 14:05
evpu, по-хорошему, документацию читать надо. Бо, хоть принципы у реляционных баз данных и общие, но реализация может иметь отличия в ту или иную сторону, причём не только у разных продуктов, но у разных версий одного и того же продукта.

Busla
25-02-2019, 20:30
Было иначе, сначала считывал, потом обновлял. »
сейчас то же самое. "атомарно" будет через join
и вообще это по уму делается через триггер

из select ничего случайным/волшебным образом не исключается

по-хорошему, документацию читать надо »
+1




© OSzone.net 2001-2012