Конкретный вопрос на собеседовании, на который никто не может ответить

nirex

Новичок
По задаче "б"
открываем транзакцию
делаем выборку с LOCK IN SHARE MODE,
если строка найдена с с <> 3 тогда update
при равенстве пишем ахтунг
иначе инсерт
закрываем транзакцию
 

DiMA

php.spb.ru
Команда форума
молодцы, почитали доку .-)

ответившим сразу - пирожок на полке .-))
 

fisher

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

DiMA

php.spb.ru
Команда форума
В именованных локах (оно же - любые виды аналогичных семафоров) есть большая проблема. Лок - тормознет на 100% все соседние потоки. А если потоки правят разные строки? Один поток: WHERE A=1 && B=2 && C=3, второй поток: WHERE A=99 && ... Все они будут залочены. Т.е. это такой же косячный вариант, как лок всей таблицы в MyISAM.

Точное дозированное решение задачи:

SELECT ... FOR UPDATE

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

Кроме того, свои локи - это дополнительная работа, многа лишних букаф. В чем смысл писать больше кода, когда мыскль сам все сделает?
 

fisher

накатила суть
>>А если потоки правят разные строки?
имя лока может быть функцией данных строки - в общем случае наоборот никакой взаимной блокировки не будет.
 

whirlwind

TDD infected, paranoid
Только я вот не совсем уверен

For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key (gap plus index-record) locks to block insertions by other sessions into the gaps covered by the range.

Что бы не страдать гемороем (особенно на собеседованиях), я бы посоветовал SERIALIZABLE, а вот уже если этого будет мало, вот тогда начинать тыркать все остальное типа REPEATABLE READ, но уже за деньги. Мы ведь до сих пор так не знаем, почему же нельзя использовать индексы.

-~{}~ 27.09.09 22:43:

PS. повторяю - я в чудеса не верю. если у тебя не будет индекса, то каким хером мускуль будет проверять диапазон? правильно, перебором. А если индекс, то почему нельзя использовать unique constraint? Не надо высасывать задачи из пальца. И вы с удивлением заметите, что вокруг вас полно умных и продвинутых ребят.
 

DiMA

php.spb.ru
Команда форума
>PS
О как. Ты хочешь сказать, что наличие/отстуствие индексов меняет результаты одного и того же SQL запроса? =)

Че ты привязался к (а)? Я уже сказал, что (а) действительно высосана из пальца. Но зато очень легко ее объяснить и поставить.

В задаче (б) есть первичный индекс. Но поле, по которому происходит разветвление логики - не входит в первичный или иные индексы, т.к. по нему не происходит никакого поиска. Задача (б) встречается на каждом шагу. Просто ты никогда не замечал этого паттерна и решал по другому. Я отстал от жизни, мне надо перестать пользоваться FOR UPDATE и решать все задачи на индексах?

Ты можешь подсказать более корректную задачу на проверку знаний блокировок внутри транзакций?

Кстати, чтобы поставить именованный лок, нужно написать 2 лишних строки кода - $lockName="name".$someId и запрос в базу с этой переменной.
 

whirlwind

TDD infected, paranoid
Автор оригинала: DiMA
>PS
О как. Ты хочешь сказать, что наличие/отстуствие индексов меняет результаты одного и того же SQL запроса? =)
результаты - ни в коем случае, скорость - да! Кароч я остальное поскипаю из уважения :) Просто я хочу сказать - чудес не бывает. Ну не выйдет сэкономить на точечных локах, если ты отказываешься от индексов из-за 50/50 селект/апдейт. Это как закон сохранения. Индекс либо есть и тратится время на его апдейт, либо его нет и ничего ты от этой выборки не получишь. Правильный ответ на твой вопрос - транзакция. Все остальное - сугубо частное. :)
 

atv

Новичок
Не надо высасывать задачи из пальца. И вы с удивлением заметите, что вокруг вас полно умных и продвинутых ребят.
Не могу не согласиться. Опыт можно получить только на практике, т.е. решая практические задачи. Если никто не может ответить на этот вопрос, это означает лишь одно, никто не сталкивался с подобной задачей на практике.

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

MiksIr

miksir@home:~$
А ничего, что select for update для проверки - существует ли такая строка, не будет работать, к примеру, в постгресе?
 

Макс

Старожил PHPClub
MiksIr
http://www.postgresql.org/docs/8.4/static/sql-select.html#SQL-FOR-UPDATE-SHARE
вроде все то же самое
 

MiksIr

miksir@home:~$
Вот и непонятно, знание чего проверяет эта задача. Рефлексы работы с MySQL/InnoDB на уровне начальника? =)
fisher вот или знал или профессионализм интуитивно подсказывает ему, что именованные локи - более правильно.
 

Sherman

Mephi
А в чем фишка? Без uniq индекса все равно можно две записи(с одинаковым значением ключей) вставить в postgresql или не понял поинта?
 

Sherman

Mephi
Beavis

Но, я не придумал, как это в postgresql обойти описанным выше способом(без индекса и любого глобал лока не меньше таблицы), не подскажешь что я просмотрел?
 

no_santa

Снегур
Сорри, а зачем вообще лок? Разве два запроса подряд не дадут требуемого эффекта?
 
Сверху